Java IO
以下資料,大部分為自己整理而來,供學習之用!
一、什麼是流
首先什麼是流:流(Stream)的概念來源於UNIX中的管道(pipe)概念,在unix中,管道是一條不間斷的位元組流,用來實現程式和程式間的通訊,或者讀寫外圍裝置、外部檔案等。流,必須有源端和目的端,可以是檔案,記憶體或者網路等。流的建立是為了更方便的處理資料的輸入輸出。
其次,對於輸入流輸出流如何區分,相信有很多人鬧不清楚,本人也是很長時間弄不太明白,簡單的來說,輸入輸出均是相對於記憶體來說,這樣就比較好理解了,簡單的來說:輸入流就是從外部檔案輸入到記憶體,輸出流主要是從記憶體輸出到檔案。
第三,類別,流可以分為位元組流和字元流。位元組流為原始資料,需要使用者讀入後進行相應的編碼轉換,而字元流的實現是居於自動轉換的,讀取資料時會把資料按照JVM的預設編碼自動轉換成字元。位元組流由inputStream和outputStream處理(注意,這個類均是抽象類,實現的是他們的子類),為了讓資料處理的更方便,java在後期版本中加上了字元流的Reader和Writer類。
二、位元組流:InputStream和OutputStream
程式可以從中連續讀取位元組的物件叫輸入流,用InputStream類完成,程式能向其中連續寫入位元組的物件叫輸出流,用OutputStream類完成。InputStream與OutputStream物件是兩個抽象類,還不能表明具體對應哪種IO裝置。它們下面有許多子類,包括網路,管道,記憶體,檔案等具體的IO裝置,如FileInputStream類對應的就是檔案輸入流,是一個節點流類,我們將這些節點流類所對應的IO源和目標稱為流節點(Node)。
InputStream定義了Java的輸入流模型。該類中的所有方法在遇到錯誤的時候都會引發IOException異常,下面是InputStream類中方法的一個簡要說明:
int read()返回下一個輸入位元組的整型表示,,如果返回-1表示遇到流的末尾,結束。
int read(byte[]b)讀入b.length個位元組放到b中並返回實際讀入的位元組數。
int read(byte[]b,int off,int len) 這個方法表示把流中的資料讀到,陣列b中,第off個開始的len個陣列元素中.
long skip(long n) 跳過輸入流上的n個位元組並返回實際跳過的位元組數。
int availabale() 返回當前輸入流中可讀的位元組數。
void mark(int readlimit)在輸入流的當前位置處放上一個標誌,允許最多再讀入readlimit個位元組。
void reset() 把輸入指標返回到以前所做的標誌處。
boolean markSupported() 如果當前流支援mark/reset操作就返回true。
void close() 在操作完一個流後要使用此方法將其關閉,系統就會釋放與這個流相關的資源。
InputStream是一個抽象類,程式中實際使用的是它的各種子類物件。不是所有的子類都會支援InputStream中定義的某些方法的,如skip,mark,reset等,這些方法只對某些子類有用。
注意點:
一個物件在沒有引用變數指向它時會變成垃圾,最終會被垃圾回收器從記憶體中清除。對於我們建立的流物件,幹嘛還要“呼叫close方法將它關閉,以釋放與其相關的資源”呢?這相關的資源到底是些什麼呢?我們在程式中建立的物件都是對應現實世界中有形或無形的事物,計算機作業系統所產生的東西當然也是現實世界中的事物,也就是說,程式中的物件也可以對應計算機作業系統所產生的一個其他東西,專業地說,這些東西叫資源,流就是作業系統產生的一種資源。當我們在程式中建立了一個IO流物件,同時系統內也會建立了一個叫流的東西,在這種情況下,計算機記憶體中實際上產生了兩個事物,一個是Java程式中的類的例項物件,一個是系統本身產生的某種資源,我們以後講到的視窗,Socket等都是這樣的情況。Java垃圾回收器只能管理程式中的類的例項物件,沒法去管理系統產生的資源,所以程式需要呼叫close方法,去通知系統釋放其自身產生的資源。
OutputStream是一個定義了輸出流的抽象類,這個類中的所有方法均返回void,並在遇到錯誤時引發IOException異常。下面是OutputStream的方法:
void write(int b) 將一個位元組寫到輸出流。注意,這裡的引數是int型,它允許write使用表示式而不用強制轉換成byte型。
void write(byte[] b) 將整個位元組陣列寫到輸出流中。
void write(byte [] b,int off,int len) 將位元組陣列b中的從off開始的len個位元組寫到輸出流。
void flush徹底完成輸出並清空緩衝區。
void close關閉輸出流。
下面是從網上找到的它們的結構圖:
三、字元流Reader和write
Java中的字元是unicode編碼,是雙位元組的,而InputStream與OutputStream是用來處理位元組的,在處理字元文字時不太方便,需要編寫額外的程式程式碼。Java為字元文字的輸入輸出專門提供了一套單獨的類,Reader、Writer兩個抽象類與InputStream、OutputStream兩個類相對應,同樣,Reader、Writer下面也有許多子類,對具體IO裝置進行字元輸入輸出,如FileReader就是用來讀取檔案流中的字元。
對於Reader和Writer,我們就不過多的說明了,大體的功能和InputStream、OutputStream兩個類相同,但並不是它們的代替者,只是在處理字串時簡化了我們的程式設計。簡單例子:
import java.io.*;
public class FileStream
{
public static void main(String[] args)
{
File f = new File("hello.txt");
try
{
FileWriter out = new FileWriter(f);
out.write("www.it315.org");
out.close();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
try
{
FileReader in = new FileReader(f);
char [] buf = new char[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
四、位元組流與字元流的轉換
前面我們講過,Java支援位元組流和字元流,我們有時需要位元組流和字元流之間的轉換。
InputStreamReader 和OutputStreamWriter
這兩個類是位元組流和字元流之間轉換的類,InputStreamReader可以將一個位元組流中的位元組解碼成字元,OuputStreamWriter將寫入的字元編碼成位元組後寫入一個位元組流。其中InputStreamReader有兩個主要的建構函式:
InputStreamReader(InputStream in) //用預設字符集建立一個InputStreamReader物件
InputStreamReader(InputStreamin,String CharsetName) //接受以指定字符集名的字串,並用//該字符集建立物件
OutputStreamWriter也有對應的兩個主要的建構函式:
OutputStreamWriter(OutputStream in) //用預設字符集建立一個OutputStreamWriter物件
OutputStreamWriter(OutputStream in,StringCharsetName) //接受以指定字符集名的字串,
//並用該字符集建立OutputStreamWriter物件
為了達到最好的效率,避免頻繁的字元與位元組間的相互轉換,我們最好不要直接使用這兩個類來進行讀寫,應儘量使用BufferedWriter類包裝OutputStreamWriter類,用BufferedReader類包裝InputStreamReader。例如:
BufferedWriter out=new BufferedWriter(newOutputStreamWriter(System.out));
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
我們接著從一個更實際的應用中來熟悉InputStreamReader的作用,怎樣用一種簡單的方式一下就讀取到鍵盤上輸入的一整行字元?只要用下面的兩行程式程式碼就可以解決這個問題:
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
String strLine = in.readLine();
相關文章
- [java IO流]之 IO概述Java
- Java IO1:IO和FileJava
- java -IO流Java
- Java IO流Java
- java - IO流Java
- Java IO流Java
- Java IO: 流Java
- Java IO: InputStreamJava
- Java IO: OutputStreamJava
- Java IO初探Java
- Java——IO流Java
- Java 非阻塞 IO 和非同步 IOJava非同步
- Java的IO流Java
- 備戰-Java IOJava
- Java IO實踐Java
- Java IO 和 NIOJava
- Java IO: 網路Java
- Java IO流操作Java
- Java IO之NIOJava
- Java IO - ReaderJava
- Java review--IOJavaView
- [Java基礎]IOJava
- 面試題-JAVA IO面試題Java
- Java 基於字元的IO Char Based IOJava字元
- Java IO8:IO簡單總結Java
- JAVA(三)JAVA常用類庫/JAVA IOJava
- java.io.EOFException java.io.ObjectInputStream$PeekInputStream.readFully 錯誤JavaExceptionObject
- Asyncdb(二):Java IO 初探Java
- Java——IO總結2Java
- 【重學Java】IO流Java
- Java:IO:深入理解Java
- Java IO流(詳細)Java
- Java IO: Reader And WriterJava
- 5⃣️ Java IO 技術Java
- Java 檔案 IO 操作Java
- Java筆記-IO流Java筆記
- 學習java io流Java
- Java 網路 IO 模型Java模型