黑馬程序員_JavaIO流(三)

字節流File讀寫操做

 字符流:java

FileReader  FileWriter數組

BufferedReader  BufferedWrtier網絡

字節流:app

FileInputStream  FileOutputStream工具

BufferedInputStream  BufferedOutputStream優化

 

需求:想要操做圖片數據,這時就要用到字節流。ui

 

import java.io.*;

class FileStream
{
    pubilc static void main(String[] args)
    {
        
    }

public static void readFile_3()throws IOException
{
FileInputStream fis = new FileInputStream("fos.txt");

//int num = fis.available();

byte[] buf = new byte[fis.available()];//定義一個剛恰好的緩衝區,不用再循環了。此方法要慎用。可能會發生內存溢出。

fis.read(buf);
//System.out.println("num"+num);

System.out.println(new String(buf));

fis.close();
}
public static void readFile_2()throws IOException { FileInputStream fis = new FileInputStream("fos.txt"); byte[] buf = new byte[1024];//建議定義1024的整數倍。 int len = 0; while((ch=len.read(buf))!=-1) { System.out println(new String(buf,0,len)); } fis.close(); } public static void readFile_1()throws IOException { FileInputStream fis = new FileInputStream("fos.txt"); int ch = 0; while((ch=fis.read())!=-1) { System.out println((char)ch); } fis.close(); } pubilc static void writerFile()throws IOException { FileOutputStream fos = new FileOutputStream("fos.txt"); fos.writer("abcde".getBytes()); fos.close();//不需刷新,但必須關閉資源。 } }

 

拷貝圖片

複製一個圖片this

思路:編碼

1,用字節讀取流對象和圖片關聯。spa

2,用字節寫入流對象建立一個圖片文件,用於存儲獲取到的圖片數據。

3,經過循環讀寫,完成數據的存儲。

4,關閉資源。

import java.io.*;

class CopyPic
{
    pubilc static void mian(String[] args)
    {
        FileOutputStream fos = null;
        FileInputStream fps = null;
        try
        {
//寫 fos
= new FileOutputStream("c:\\2.bmp");
//讀 fps
= new FileInputStream("c:\\1.bmp"); byte[] buf = new byte[1024]; int len = 0; while((len=fis.read(buf))!=-1) { fos.write(buf,0,len); } }
catch(IOException e) { throws new RuntimeException("複製文件失敗"); }
finally { try { if(fis!=null) fis.close(); } catch(IOException e) { throws new RuntimeException("讀取關閉失敗"); } try { if(fos!=null) fis.close(); } catch(IOException e) { throws new RuntimeException("寫入關閉失敗"); } } } }

 

 字節流的緩衝區

演示MP3的複製,經過緩衝區。

import java.io.*;

class CopyMp3
{
    public static void mian(String[] args)throws IOException
    {
        long start = System.currentTimeMillis();
        Copy_1();
        long end = System.currentTimeMillis();

        System.out.println((end-start)+"毫秒");
    }

    //經過字節流的緩衝區完成複製。
    public static void Copy_1()throws IOException
    {
        BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\0.mp3"));

        BufferedOnputStream bufos = new BufferedOnputStream(new FileOnputStream("c:\\1.mp3"));

        int by = 0;

        while((by=bufis.read())!=-1)
        {
            bufos.write(by);
        }

        bufos.close();
        bufis.close();
    }
}

  

 自定義字節流的緩衝區-read和write的特色

 

import java.io.*;

class MyBufferedInputStream;
{
    private InputStream in;

    private byte[] buf = new byte[1024*4];

    private int pos = 0,count = 0; 

    MyBufferedInputStream(InputStream in)
    {
        this.in = in;
    }

    //一次讀一個字節,從緩衝區(字節數組)獲取。
    public int myRead()throw IOException
    {
        //經過int對象讀取硬盤上數據,並存儲buf中。
        if(count==0)
        {
            count = in.read(buf);

            if(count<0);
                return -1;

            byte b = buf[pos];

            count--;

            pos++;
 
            return b&255;
        }
        else if(count>0)
        {
            byte b = buf[pos];
   
             count--;

             pos++;

            return b&Oxff; 
        }

        return -1;
    }

    public void myClose()throw IOException
    {
        in.close();
    }
}

 

 

注意:

read方法返回的是int類型,但仍是-1。是-1的緣由是由於在8個1面前補的是1所致使的。那麼我只要在前面補0,既能夠保留原字節數據不變,又能夠避免-1的出現。

怎麼補0呢?在返回數據時&上255/Oxff(255的十六進制表現形式)。

read的方法將數據進行提高(是爲了不-1的發生),write方法將數據強制轉換再返回(只寫最低8位,有效數據)。

 

 讀取鍵盤錄入

System.out:對應的是標準輸出設備,控制檯。

System.in:對應的是標準的輸入設備:鍵盤。

import java.io.*;

class ReadIn
{
    public static void main(String[] args)throws IOException
    {
        InputStream in = System.in;

        int ch = in.read();//此方法是一個阻塞式方法。
 
        System.out.println(ch);//被提高後,打印出來的是數字。

        int ch = in.read();
 
        System.out.println(ch);//回車符在編碼邊裏面'\r'=13,'\n'=10
    }
}

 

需求:經過鍵盤錄入數據。當錄入一行數據後,就將該行數據進行打印,若是錄入的數據是over,那麼中止錄入。

import java.io.*;

class ReadIn
{
    public static void main(String[] args)throws IOException
    {
        InputStream in = Ststem.in;

        StringBuilder sb = new StringBuilder();

        while(true)
        {
            int ch = in.read();

            if(ch=='\r')
                cuntinue;
            if(ch=='\n')
            {
                String s = sb.toString();
                if("over".equals(s))
                    break;
                System.out.println(s.toUpperCase());
                sb.delete(0,sb.length());//打印一次就要清空緩衝區一次。
            }
            else
            {
                sb.append((char)ch);
            }
        }
    }
}

 

 讀取轉換流

經過剛纔的鍵盤錄入一行數據並打印其大寫,發現其實就是都一行數據的原理,也就是readLine方法。能不能直接使用readLine方法開完成鍵盤錄入的一行數據讀取呢?

readLine方法是字符流BufferedReader類中的方法。而鍵盤錄入的read方法是字節流InputStream的方法。

那麼能不能將字節流轉成字符流再使用字符流緩衝區的readLine方法呢?

import java.io.*;

class TransStreamDemo
{
    public static void main(String[] args)throws IOException
    {
        //獲取鍵盤錄入對象。
        InputStream in = System.in;

        //將字節流對象轉換成字符流對象,使用轉換流,InputStreamReader
        InputStreamReader isr = new InputStreamReader(in);

        //爲了提升效率,將字符串進行緩衝區技術高效操做,使用BuferedReader.
        BufferedReader bufr = new BufferedReader(isr);

        String line = null;

        while((line = bufr.readLine())!=null)
        {
            if("over".equals(line))
                break;
            System.out.println(line.toUpperCase());
        }
        
        bufr.close();//能夠省略不寫。最終都是System.in在操做。
    }
}

 

 寫入轉換流

System.out返回的是PrintStream,是OutputStream的子類。

import java.io.*;

class TransStreamDemo
{
    public static void main(String[] args)throws IOException
    {
       
        InputStream in = System.in;

        InputStreamReader isr = new InputStreamReader(in);

        BufferedReader bufr = new BufferedReader(isr);

        OutputStream os = System.out;

        OutputStreamWriter osw = new OutputStreamWriter(os);

        BufferedWriter bufw = new BufferedWriter(osw);

        String line = null;

        while((line = bufr.readLine())!=null)
        {
            if("over".equals(line))
                break;

            bufw.writer(line.toUpperCase());
            bufw.newline();
            bufw.flush();

            //此方法不跨平臺:osw.write(line.toUpperCase()+"'\r\n");
            //osw.flush();

            //System.out.println(line.toUpperCase());
        }
        
        bufr.close();//能夠省略不寫。最終都是System.in在操做。
    }
}

 

代碼進行優化後:

import java.io.*;

class TransStreamDemo
{
    public static void main(String[] args)throws IOException
    {   //鍵盤錄入的最多見寫法。
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

        String line = null;

        while((line = bufr.readLine())!=null)
        {
            if("over".equals(line))
                break;

            bufw.writer(line.toUpperCase());
            bufw.newline();
            bufw.flush();
        }
    }
}

 

流操做規律-1

1,

源:鍵盤錄入。

目的:控制檯。

 

2,需求:想把鍵盤錄入的數據存儲到一個文件中。

源:鍵盤。

目的:文件。

 

3,需求:想要將一個文件的數據打印在控制檯上。

源:文件。

目的:控制檯。 

 

源:

BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));

目的: 

BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

流操做的基本規律:最痛苦的是流對象有不少,不知道用哪個。

經過三個明確來完成。

1,明確源和目的。

  源:輸入流。InputStream  Reader

  目的:輸出流。OutputStream  Writer

2,操做的數據是不是純文本。 

  是:字符流。

  不是:字節流。

3,當體系明確後,再明確要使用哪一個具體的對象。

  經過設備來進行區分:

  源設備:內存,硬盤,鍵盤。

  目的設備:內存,硬盤,控制檯。

需求:

1,將一個文本文件中數據存儲到另外一個文件中,複製文件。

  源:由於是源,因此使用讀取流。InputStream  Reader

  是否是操做文本文件?是。這是就能夠選擇Reader,這樣體系就明確了。

  接下來明確要使用該體系中的哪一個對象。

  明確設備:硬盤,上的一個文件。

  Reader體系中能夠操做文件對象的是FileReader。

 

  是否須要提升效率:是!加入Reader體系中緩衝區BufferedReader。

  FileReader fr = new FielReader("a.txt");

  BufferedReader bufr = new BufferedReader(fr);

 

  目的:OutputStream  Writer

  是不是純文本呢? 是。用Writer.

  設備:硬盤。一個文件。

  Writer體系中能夠操做文件的對象是FileWriter。

 

  是否須要提升效率:是!加入Writer體系中緩衝區BufferedWriter。

  FileWriter fw = new FileWriter("b,txt");

  BufferedWriter bufw = new BufferedWriter(fw);

 

練習:將一個圖片文件中數據存儲到另外一個文件中,複製文件。要按照以上格式本身完成三個明確。

 

流操做規律-2

 2,需求:將鍵盤錄入的數據保存到一個文件中。

  這個需求中有源和目的都存在。那麼分別分析。

  源:InputStream  Reader

  是否是純文本?是。Reader

  設備:鍵盤。對應的對象是System.in。

  不是選擇Reader嗎?System.in對應的不是字節流嗎?

  爲了操做鍵盤的文本數據方便,轉成字符流按照字符串操做是最方便的。

  因此既然明確了Reader,那麼就將System.in轉換成Reader。

  用了Reader體系中轉換流,InputStreamReader

  InputStreamReader isr = new InputStreamReader(System.in);

  須要提升效率嗎?須要。BufferedReader

  BufferedReader bufr = new BufferedReader(isr);

 

  目的:OutputStream  Writer

  是不是純文本?是!Writer

  設備:硬盤。一個文件。使用FileWriter.

  FileWriter fw = new FileWriter("c.txt");

  須要提升效率嗎?須要。

  BufferedWriter bufw = new BufferedWriter(fw);


 

  擴展一下,想要把錄入的數據按照指定的編碼表(utf-8),將數據存到文件中。

  

  目的:OutputStream  Writer

  是不是純文本?是!Writer

  設備:硬盤。一個文件。使用FileWriter.(使用的是默認的編碼表GBK)

  可是存儲時須要加入指定編碼表UTF-8,而指定的編碼表只有轉換流能夠指定。因此要使用的對象是OutputStreamWriter。

  而該轉換流對象要接收一個字節輸出流,並且還能夠操做文件的字節輸出流。FileOutputStream。

  OutputStreamWriter osw = new OutputStreamWriter(new FIleOutputStream("d.txt"),"UTF-8");

  須要高效嗎?須要。

  BufferedWriter bufw = new BufferedWriter(osw);

  因此,記住:轉換流何時使用。字符和字節之間的橋樑,一般,涉及到字符編碼轉換時,須要用到轉換流。

 

練習:將一個文本數據打印在控制檯上,要按照以上格式本身完成三個明確。

  

 改變標準輸入輸出設備

 System裏提供兩個靜態方法來改變標準的的輸入輸出設備。

1,static void setIn(InputStream in):從新分配「標準」輸入流。//System.in(new FileInputStream("PersonDemo.java");

2,static void setOut(PrintStream out):從新分配「標準」輸出流。//System.out(new PrintStream("zz.txt");

 

異常的日誌信息

 

import java.io.*;
import java.util.*;
import java.text.*;

class ExceptionInfo
{
    public static void main(String[] args)
    {
        try
        {
            int[] arr = new int[2];
            System.out.println(arr[3]);
        }
        catch(Exceptiom e)
        {
            try
            {
                Date d = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD HH:mm:ss");
                String s = sdf.format(d);

                PrintStream ps = new PrintStream("exception.log");
                //ps.write(d.toString().getBytes());
                ps.println(d.toString());
                System.setOut(ps);
            }
            catch(IOException ex)
            {
                throw new RuntimeException("日誌文件建立失敗");
            }
            e.printStackTrace(System.out);//將日誌信息存到指定文件
        }
    }
}

 

LOG4G:網絡工具包,專門用於創建Java的日誌文件信息。  

 

 系統信息

Properties類中的方法:

1,void list(PrintStream out):將屬性列表輸出到指定的輸出流。

2,void list(PrintWriter out):將屬性列表輸出到指定的輸出流。

import java.util.*;
import java.io.*;

class SystemInfo
{
    public static void main(String[] args)
    {
        Properties prop = System.getProperties();

        //System.out.println(prop);
        prop.list(new PrintStream("sysinfo.txt");
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

,,,,。。。。。。。。。。。。。。。。。。。。。。。。。

相關文章
相關標籤/搜索