Java中I/O操作總結

原文地址:https://mp.weixin.qq.com/s/xBQYOG6uF-ORuuvEL80Mhg

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

數據流是一串連續不斷的數據的集合,就象水管裏的水流,在水管的一端一點一點地供水,而在水管的另一端看到的是一股連續不斷的水流。數據寫入程序可以是一段、一段地向數據流管道中寫入數據,這些數據段會按先後順序形成一個長的數據流。對數據讀取程序來說,看不到數據流在寫入時的分段情況,每次可以讀取其中的任意長度的數據,但只能先讀取前面的數據後,再讀取後面的數據(不能隨機讀取)。不管寫入時是將數據分多次寫入,還是作爲一個整體一次寫入,讀取時的效果都是完全一樣的。

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

當程序需要讀取數據的時候,就會建立一個通向數據源的連接,這個數據源可以是文件,內存,或是網絡連接。類似的,當程序需要寫入數據的時候,就會建立一個通向目的地的連接。

數據流分類:

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

概覽

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

Java I/O主要包括如下3層次:

流式部分——最主要的部分。如:OutputStream、InputStream、Writer、Reader等

非流式部分——如:File類、RandomAccessFile類和FileDescriptor等類

其他——文件讀取部分的與安全相關的類,如:SerializablePermission類,以及與本地操作系統相關的文件系統的類,如:FileSystem類和Win32FileSystem類和WinNTFileSystem類。

主要類如下:

File(文件特徵與管理):用於文件或者目錄的描述信息,例如生成新目錄,修改文件名,刪除文件,判斷文件所在路徑等。

InputStream(字節流,二進制格式操作):抽象類,基於字節的輸入操作,是所有輸入流的父類。定義了所有輸入流都具有的共同特徵。

OutputStream(字節流,二進制格式操作):抽象類。基於字節的輸出操作。是所有輸出流的父類。定義了所有輸出流都具有的共同特徵。

Reader(字符流,文本格式操作):抽象類,基於字符的輸入操作。

Writer(字符流,文本格式操作):抽象類,基於字符的輸出操作。

RandomAccessFile(隨機文件操作):它的功能豐富,可以從文件的任意位置進行存取(輸入輸出)操作。

這裏寫圖片描述

I/O流

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

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

這裏寫圖片描述

按來源/去向分類:

File(文件): FileInputStream, FileOutputStream, FileReader, FileWriter

byte[]:ByteArrayInputStream, ByteArrayOutputStream

Char[]: CharArrayReader, CharArrayWriter

String: StringBufferInputStream, StringReader, StringWriter

網絡數據流: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:

FileInputStream把一個文件作爲InputStream,實現對文件的讀取操作

ByteArrayInputStream:把內存中的一個緩衝區作爲InputStream使用

StringBufferInputStream:把一個String對象作爲InputStream

PipedInputStream:實現了pipe的概念,主要在線程中使用

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:

ByteArrayOutputStream:把信息存入內存中的一個緩衝區中

FileOutputStream:把信息存入文件中

PipedOutputStream:實現了pipe的概念,主要在線程中使用

SequenceOutputStream:把多個OutStream合併爲一個OutStream

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

有兩個需要注意的:

InputStreamReader : 從輸入流讀取字節,在將它們轉換成字符。

BufferReader :接受Reader對象作爲參數,並對其添加字符緩衝器,使用readline()方法可以讀取一行。

如何選擇I/O流

確定是輸入還是輸出

輸入:輸入流 InputStream Reader
輸出:輸出流 OutputStream Writer

明確操作的數據對象是否是純文本

是:字符流 Reader,Writer
否:字節流 InputStream,OutputStream

明確具體的設備。

文件:
讀:FileInputStream,, FileReader,
寫:FileOutputStream,FileWriter

數組:
byte[ ]:ByteArrayInputStream, ByteArrayOutputStream
char[ ]:CharArrayReader, CharArrayWriter

String:
StringBufferInputStream(已過時,因爲其只能用於String的每個字符都是8位的字符串), StringReader, StringWriter

Socket流
鍵盤:用System.in(是一個InputStream對象)讀取,用System.out(是一個OutoutStream對象)打印

是否需要轉換流

是,就使用轉換流,從Stream轉化爲Reader、Writer:InputStreamReader,OutputStreamWriter

是否需要緩衝提高效率

是就加上Buffered:BufferedInputStream, BufferedOuputStream, BufferedReader, BufferedWriter

是否需要格式化輸出

示例代碼

將標準輸入(鍵盤輸入)顯示到標準輸出(顯示器),支持字符。

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();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章