Java I/O 總結

Java中I/O操做主要是指使用Java進行輸入,輸出操做. Java全部的I/O機制都是基於數據流進行輸入輸出,這些數據流表示了字符或者字節數據的流動序列。java

數據流是一串接二連三的數據的集合,就象水管裏的水流,在水管的一端一點一點地供水,而在水管的另外一端看到的是一股接二連三的水流。數據寫入程序能夠是一段、一段地向數據流管道中寫入數據,這些數據段會按前後順序造成一個長的數據流。對數據讀取程序來講,看不到數據流在寫入時的分段狀況,每次能夠讀取其中的任意長度的數據,但只能先讀取前面的數據後,再讀取後面的數據(不能隨機讀取)。無論寫入時是將數據分屢次寫入,仍是做爲一個總體一次寫入,讀取時的效果都是徹底同樣的。數組

簡而言之:數據流是一組有序,有起點和終點的字節的數據序列。包括輸入流和輸出流。安全

當程序須要讀取數據的時候,就會創建一個通向數據源的鏈接,這個數據源能夠是文件,內存,或是網絡鏈接。相似的,當程序須要寫入數據的時候,就會創建一個通向目的地的鏈接。網絡

數據流分類:dom

流序列中的數據既能夠是未經加工的原始二進制數據,也能夠是經必定編碼處理後符合某種格式規定的特定數據。所以Java中的流分爲兩種: 1) 字節流:數據流中最小的數據單元是字節 2) 字符流:數據流中最小的數據單元是字符, Java中的字符是Unicode編碼,一個字符佔用兩個字節。編碼

概覽

http://Java.io包中最重要的就是5個類和一個接口。5個類指的是File、OutputStream、InputStream、Writer、Reader;一個接口指的是Serializable。掌握了這些就掌握了Java I/O的精髓了。spa

Java I/O主要包括以下3層次:操作系統

  1. 流式部分——最主要的部分。如:OutputStream、InputStream、Writer、Reader等
  2. 非流式部分——如:File類、RandomAccessFile類和FileDescriptor等類
  3. 其餘——文件讀取部分的與安全相關的類,如:SerializablePermission類,以及與本地操做系統相關的文件系統的類,如:FileSystem類和Win32FileSystem類和WinNTFileSystem類。

主要類以下:線程

  1. File(文件特徵與管理):用於文件或者目錄的描述信息,例如生成新目錄,修改文件名,刪除文件,判斷文件所在路徑等。
  2. InputStream(字節流,二進制格式操做):抽象類,基於字節的輸入操做,是全部輸入流的父類。定義了全部輸入流都具備的共同特徵。
  3. OutputStream(字節流,二進制格式操做):抽象類。基於字節的輸出操做。是全部輸出流的父類。定義了全部輸出流都具備的共同特徵。
  4. Reader(字符流,文本格式操做):抽象類,基於字符的輸入操做。
  5. Writer(字符流,文本格式操做):抽象類,基於字符的輸出操做。
  6. RandomAccessFile(隨機文件操做):它的功能豐富,能夠從文件的任意位置進行存取(輸入輸出)操做

I/O流

http://java.io包裏有4個基本類:InputStream、OutputStream及Reader、Writer類,它們分別處理字節流和字符流。3d

其餘各類各樣的流都是由這4個派生出來的。

按來源/去向分類:

  1. File(文件): FileInputStream, FileOutputStream, FileReader, FileWriter
  2. byte[]:ByteArrayInputStream, ByteArrayOutputStream
  3. Char[]: CharArrayReader, CharArrayWriter
  4. String: StringBufferInputStream, StringReader, StringWriter
  5. 網絡數據流:InputStream, OutputStream, Reader, Writer

InputStream

InputStream 爲字節輸入流,它自己爲一個抽象類,必須依靠其子類實現各類功能,此抽象類是表示字節輸入流的全部類的超類。 繼承自InputStream 的流都是向程序中輸入數據的,且數據單位爲字節(8bit);

InputStream是輸入字節數據用的類,因此InputStream類提供了3種重載的read方法.Inputstream類中的經常使用方法:

  • public abstract int read( ):讀取一個byte的數據,返回值是高位補0的int類型值。若返回值=-1說明沒有讀取到任何字節讀取工做結束。
  • public int read(byte b[ ]):讀取b.length個字節的數據放到b數組中。返回值是讀取的字節數。該方法其實是調用下一個方法實現的
  • public int read(byte b[ ], int off, int len):從輸入流中最多讀取len個字節的數據,存放到偏移量爲off的b數組中。
  • public int available( ):返回輸入流中能夠讀取的字節數。注意:若輸入阻塞,當前線程將被掛起,若是InputStream對象調用這個方法的話,它只會返回0,這個方法必須由繼承InputStream類的子類對象調用纔有用,
  • public long skip(long n):忽略輸入流中的n個字節,返回值是實際忽略的字節數, 跳過一些字節來讀取
  • public int close( ) :使用完後,必須對咱們打開的流進行關閉。

來看看幾種不一樣的InputStream:

  1. FileInputStream把一個文件做爲InputStream,實現對文件的讀取操做
  2. ByteArrayInputStream:把內存中的一個緩衝區做爲InputStream使用
  3. StringBufferInputStream:把一個String對象做爲InputStream
  4. PipedInputStream:實現了pipe的概念,主要在線程中使用
  5. SequenceInputStream:把多個InputStream合併爲一個InputStream

OutputStream

OutputStream提供了3個write方法來作數據的輸出,這個是和InputStream是相對應的。   

  • public void write(byte b[ ]):將參數b中的字節寫到輸出流。
  • public void write(byte b[ ], int off, int len) :將參數b的從偏移量off開始的len個字節寫到輸出流。
  • public abstract void write(int b) :先將int轉換爲byte類型,把低字節寫入到輸出流中。
  • public void flush( ) : 將數據緩衝區中數據所有輸出,並清空緩衝區。
  • public void close( ) : 關閉輸出流並釋放與流相關的系統資源。

幾種不一樣的OutputStream:

  1. ByteArrayOutputStream:把信息存入內存中的一個緩衝區中
  2. FileOutputStream:把信息存入文件中
  3. PipedOutputStream:實現了pipe的概念,主要在線程中使用
  4. SequenceOutputStream:把多個OutStream合併爲一個OutStream

Reader和InputStream相似;Writer和OutputStream相似。

有兩個須要注意的:

  1. InputStreamReader : 從輸入流讀取字節,在將它們轉換成字符。
  2. BufferReader :接受Reader對象做爲參數,並對其添加字符緩衝器,使用readline()方法能夠讀取一行。

如何選擇I/O流

1.肯定是輸入仍是輸出
輸入:輸入流 InputStream Reader
輸出:輸出流 OutputStream Writer

2. 明確操做的數據對象是不是純文本
是:字符流 Reader,Writer
否:字節流 InputStream,OutputStream

3. 明確具體的設備。

    • 文件:
      讀:FileInputStream,, FileReader,
      寫:FileOutputStream,FileWriter
    • 數組:
      byte[ ]:ByteArrayInputStream, ByteArrayOutputStream
      char[ ]:CharArrayReader, CharArrayWriter
    • String:
      StringBufferInputStream(已過期,由於其只能用於String的每一個字符都是8位的字符串), StringReader, StringWriter
    • Socket流
      鍵盤:用http://System.in(是一個InputStream對象)讀取,用System.out(是一個OutoutStream對象)打印

4. 是否須要轉換流
是,就使用轉換流,從Stream轉化爲Reader、Writer:InputStreamReader,OutputStreamWriter

5. 是否須要緩衝提升效率
是就加上Buffered:BufferedInputStream, BufferedOuputStream, BufferedReader, BufferedWriter

6. 是否須要格式化輸出

示例代碼

  • 將標準輸入(鍵盤輸入)顯示到標準輸出(顯示器),支持字符。
char ch;
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));  //將字節流轉爲字符流,帶緩衝
try {
    while ((ch = (char) in.read()) != -1){
        System.out.print(ch);
    }
} catch (IOException e) {
    e.printStackTrace();
}
  • 將AtomicityTest.java的內容打印到顯示器

方法一:

BufferedReader in = new BufferedReader(new FileReader("AtomicityTest.java"));
String s;
try {
    while ((s = in.readLine()) != null){
        System.out.println(s);
    }
    in.close();
} catch (IOException e) {
    e.printStackTrace();
}

方法二:

FileReader in = new FileReader("AtomicityTest.java");
int b;
try {
    while ((b = in.read()) != -1){
        System.out.print((char)b);
    }
    in.close();
} catch (IOException e) {
    e.printStackTrace();
}

方法三:(有可能出現亂碼)

FileInputStream in = new FileInputStream("AtomicityTest.java");
int n = 50;
byte[] buffer = new byte[n];
try {
    while ((in.read(buffer,0,n) != -1 && n > 0)){
        System.out.print(new String(buffer));
    }
    in.close();
} catch (IOException e) {
    e.printStackTrace();
}
  • 將文件A的內容拷貝到文件B
FileInputStream in = new FileInputStream("AtomicityTest.java");
FileOutputStream out = new FileOutputStream("copy.txt");
int b;
while ((b = in.read()) != -1){
    out.write(b);
}
out.flush();
in.close();
out.close();
  • 將標準輸入的內容寫入文件
Scanner in = new Scanner(System.in);
FileWriter out = new FileWriter("systemIn.log");
String s;
while (!(s = in.nextLine()).equals("Q")){
    out.write(s + "\n");
}
out.flush();
out.close();
in.close();
相關文章
相關標籤/搜索