1.什麼是IO
Java中I/O作業主要是指使用Java輸入,輸出作業. Java所有的I/O機制都是基於資料流進行輸入輸出,這些資料流表示了字元或位元組資料的流動序列。 Java的I/O流提供了讀寫資料的標準方法。任何Java中表示資料來源的物件都會提供以資料流的方式讀寫它的資料的方法。
Java.io是大多數以資料流為導向的輸入/輸出類別的主要軟體套件。此外,Java也對區塊傳輸提供支持,在核心庫 java.nio中採用的便是區塊IO。
流IO的好處是簡單易用,缺點是效率較低。塊IO效率很高,但程式比較複雜。
Java IO模型 :
Java的IO模型設計非常優秀,它使用Decorator模式,以功能劃分Stream,您可以動態組裝這些Stream,以便獲得您需要的功能。例如,您需要一個具有緩衝的檔案輸入流,則應當組合使用FileInputStream和BufferedInputStream。
#2.資料流的基本概念
資料流是一串連續不斷的資料的集合,就像水管裡的水流,在水管的一端一點一點地供水,而在水管的另一端看到的是一股連續不斷的水流。資料寫入程序可以是一段、一段地向資料流管道寫入數據,這些資料段會依照先後順序形成一個長的資料流。對資料讀取程式來說,看不到資料流在寫入時的分段情況,每次可以讀取其中的任意長度的數據,但只能先讀取前面的資料後,再讀取後面的數據。不管寫入時是將資料分多次寫入,還是作為一個整體一次寫入,讀取時的效果都是完全一樣的。
「串流是磁碟或其它週邊裝置中儲存的資料的來源點或終點。」
在電腦上的資料有三種儲存方式,一種是外存,一種是內存,一種是快取。例如電腦上的硬碟,磁碟,U盤等都是外存,在電腦上有記憶體條,快取是在CPU裡面的。外存的儲存量最大,其次是內存,最後是緩存,但是外存的資料的讀取最慢,其次是內存,快取最快。這裡總結從外存讀取資料到記憶體以及將資料從記憶體寫入外存。對於記憶體和外存的理解,我們可以簡單的理解為容器,即外存是一個容器,記憶體又是另一個容器。那又怎樣把放在外存這個容器內的資料讀取到記憶體這個容器以及怎麼把記憶體這個容器裡的資料存到外存呢?
在Java類別庫中,IO部分的內容是龐大的,因為它所涉及的領域很廣泛:
## 標準輸入輸出,檔案的操作,網路上的資料流,字串流,物件流,zip檔案流等等,java中將輸入輸出抽象化稱為流,就好像水管,將兩個容器連接起來。將資料沖外存讀取到記憶體中的稱為輸入流,將資料從記憶體寫入外存中的稱為輸出流。
流是一個很形象的概念,當程式需要讀取資料的時候,就會開啟一個通往資料來源的串流,這個資料來源可以是文件,內存,或是網路連線。類似的,當程式需要寫入資料的時候,就會開啟一個通往目的地的流。
程式寫入資料到輸出流。將程式中的資料輸出到外界(顯示器、印表機、檔案、網路…)的通訊通道。
採用資料流的目的是讓輸出輸入獨立於裝置上。
Input Stream不關心資料來源來自何種裝置(鍵盤,文件,網路)
Output Stream不關心資料的目的是何種裝置(鍵盤,文件,網路)
流序列中的資料既可以是未經加工的原始二進位數據,也可以是經一定編碼處理後符合某種格式規定的特定資料。因此Java中的流分為兩種:
1) 位元組流:資料流中最小的資料單元是位元組
2) 字元流:數據流中最小的資料單元是字符, Java中的字符是Unicode編碼,一個字符佔用兩個位元組。
#3. 標準I/O
Java程式可透過命令列參數與外部進行簡短的資訊交換,同時,也規定了與標準輸入、輸出設備,如鍵盤、顯示器進行資訊交換的方式。而透過文件可以與外界進行任意資料形式的資訊交換。
#public class TestArgs {
# for () i = for (#int i =
##public final class System
Object{
## static PrintStream err;//標準錯誤流(輸出)
##
static InputStream in;###//標準輸入(鍵盤輸入流) ################## ###static PrintStream out串流(顯示器輸出流) ##################} ##################### ###注意:
(1)System類別不能建立物件,只能直接使用它的三個靜態成員。
(2)每當main方法被執行時,就自動產生上述三個物件。
1) 標準輸出流 System.out
# System.out向標準輸出裝置輸出資料,其資料型別為PrintStream。方法:
Void print(參數)
Void println(參數)
#
#2)標準輸入流 System.in
System.in讀取標準輸入裝置資料(從標準輸入取得數據,一般是鍵盤),其資料類型為InputStream。方法:
int read() //返回ASCII碼。若,回傳值=-1,表示沒有讀取到任何位元組讀取工作結束。
int read(byte[] b)//讀入多個位元組到緩衝區b中傳回值是讀入的位元組數
#例如:
#import java.io.*;
#public class StandardInputOutput {
public static void main(String public #static void main(String
publicpublic #static void main(String
#int b;
) b);
3)標準錯誤流
System.err輸出標準錯誤 ,其資料類型為PrintStream。可查閱
API取得詳細說明。
標準輸出透過System.out呼叫println方法輸出參數並換行,而print方法輸出參數但不換行。 println或print方法都通 過
重載實作了輸出基本資料型別的多個方法,包括輸出參數型別為boolean、char、int、long、float和double。同時,也重載實作 了輸出參數類型為char[]、String和Object的方法。其中,print(Object)和println(Object)方法在運行時將調 用參數Object的toString方法。
#import java.io.BufferedReader;
#import java.io.InputStreamReader;
# public
######## ###public ## ##static ###void main(String args[]) { #############o 和
new InputStreamReader(System.in);
# ir);System.out.println("Unix系統: ctrl-d 或 ctrl-c
"## +
"\nWindows系統: ctrl-z 退出");// readLine()方法使用時若發生I/O錯誤,且會拋出一個「Exception」
null) {
}
catch (IOException e) {# }
#4.java.IO層級體系結構
。 5個類別指的是File、OutputStream、InputStream、Writer、Reader;一個介面指的是Serializable.掌握了這些IO的核心操作那麼對於Java中的IO體係也就有了一個初步的認識了 Java I/O主要包含以下幾個層次,包含三個部分:
1.串流部分
2.非串流部分
3.其他類別
相關的類,如:SerializablePermission類,以及與本機作業系統相關的
檔案系統 主要的類別如下:
刪除
文件,判斷文件所在路徑等。2. InputStream(二進位格式運算):抽象類別,基於位元組的輸入操作,是所有輸入流的父類別。定義了所有輸入流都具有的共同特徵。
3. OutputStream(二進位格式運算):抽象類別。基於位元組的輸出操作。是所有輸出流的父類別。定義了所有輸出流都具有的共同特徵。
Java中字元是採用Unicode標準,一個字元是16位,即一個字元使用兩個位元組來表示。為此,JAVA中引入了處理字元的流。
4. Reader(檔案格式操作):抽象類,基於字元的輸入操作。
5. Writer(檔案格式操作):抽象類別,基於字元的輸出運算。
6. RandomAccessFile(隨機檔案操作):它的功能豐富,可以從檔案的任何位置存取(輸入輸出)動作。
Java中IO流的體系結構如圖:
#5. 非串流檔案類別--File類別
在Java語言的java.io套件中,由File類別提供了描述檔案和目錄的操作與管理方法。但File類不是InputStream、OutputStream或Reader、Writer的子類,因為它不負責資料的輸入輸出,而專門用來管理磁碟檔案與目錄。
作用:File類別主要用於命名檔案、查詢檔案屬性和處理檔案目錄。
public class File extends Object
implements Serializable,Comparable
##{}
,以不同的參數形式靈活地接收檔案和目錄名稱資訊。建構子:
1)File (String pathname)
例:File f1=new File("FileTest1.txt"); //建立檔案物件f1,f1所指的檔案是在目前目錄下建立的FileTest1.txt2)File (String parent , String child)
2)File (String parent , String child)
例:File f2=new File(“D:\\
dir1","FileTest2.txt") ;// 注意:D:\\dir1目錄事先必須存在,否則異常
3)File (File parent , String child)
例:File f4=new File("\\dir3");
File f5=new File(f4,"FileTest5.txt");; .mkdir()先創建
一個對應於某磁碟檔案或目錄的File物件一經創建, 就可以透過呼叫它的方法來取得檔案或目錄的屬性。
2)public boolean isFile( ) 判斷檔案或目錄 ## ## 4)public String getName( ) 傳回檔案名稱或目錄名稱
5)public String getPath( ) 傳回檔案或目錄的路徑。
6)public long length( ) 取得檔案的長度 7)public String[ ] list ( ) 將目錄中所有檔案名稱儲存在字串陣列
中傳回。
File類別中也定義了一些管理檔案或目錄管理、操作的方法,常用的方法有:
delete
( ); 刪除檔案### 3) public boolean mkdir( ); 建立目錄############範例:####
#import java.io.File;
public
class TestFile {class TestFile { public static
void main(String args[])"\\root"); #
new File(dir,, "fileTwo.java");
// 檔案物件建立後,指定的檔案或目錄不一定會在實體上存在
# #if
(!dir.exists())## if (!f1.exists())
"f1's AbsolutePath= " + f1.getAbsolutePath()); ## =" + f1.canRead());
System.out.println("f1's len= " + f1.println("f1's len= " + f1.
String[] FL;
"is in \\root"); } ## println(
"there are" + count +}
}
##說明: File類別的方法:
6. Java.IO串流類別庫
#
#輸入/輸出 | #位元組流 | |
字元流 | ||
#Inputstream | # #Reader |
Java中其他多元變化的流皆是由它們衍生出來的:
## JDK1.4版本開始引進了新I/O類別庫,它位於java .nio套件中,新I/O類別庫利用通道和緩衝區等來提高I/O操作的效率。
在java.io套件中, java.io.InputStream 表示位元組輸入流, java.io.OutputStream表示位元組輸出流,處於java.io套件最頂層。這兩個類別都是抽象類,也就是說它們不能被實例化,必須產生子類別之後才能實現一定的功能。
一、依I/O型別來總體分類:
1. Memory 1)從/向記憶體數組讀寫資料: CharArrayReader、 CharArrayWriter、ByteArrayInputStream、ByteArrayOutputStream 讀寫資料StringReader、StringWriter、StringBufferInputStream
2.Pipe管道 實作管道的輸入與輸出(進程間通訊): PipedReader、PipedWriter、PipedInputStream、PipedOutputStreamStreamStreamStream #3.流。對檔案進行讀取、寫入操作:FileReader、FileWriter、FileInputStream、FileOutputStream
4. ObjectSerialization 物件輸入、輸出 :ObjectInputStream、ObjectOutputStream
# # :ObjectInputStream、ObjectOutputStream## #o5.Data
#5.Data#5.Data15.Data5.基本資料型別讀取、寫入(處理的資料是Java的基本型別(如布林型,位元組,整數
與浮點數)):DataInputStream、DataOutputStream 6.Printing
包含方便的列印方法:PrintWriter、PrintStream 7.Buffering緩衝
在讀入或寫出時,對資料進行緩存,以減少I/O的次數:BufferedReader、BufferedWriter、BufferedInputStream、 BufferedOutputStream 8.Filtering #濾流
,在資料進行讀取或寫入時進行過濾:FilterReader、FilterWriter、FilterInputStream、FilterOutputStream過##o## 輸入 把多個輸入流連接成一個輸入流:SequenceInputStream
10.Counting計數 讀入資料時對行記數:LineNumberReader、LineNumberInputStream #o##11. Peeking Ahead 透過快取機制,進行預讀:PushbackReader、PushbackInputStream
12.Converting between Bytes and Characters 依照一定的編碼/解碼標準將位元組流轉換為字元流,或進行反向轉換(Stream到Reader,Writer的轉換類別):InputStreamReader、OutputStreamWriter
二、依資料來源(去向)分類:
#1、File(檔案): FileInputStream , FileOutputStream, FileReader, FileWriter 2、byte[]:ByteArrayInputStream, ByteArrayOutputStream 3、Char[]: CharArrayReader, CharArrayWriter
4、String: StringBufferInputStreamStream 資料流, :InputStream, OutputStream, Reader, Writer
#
抽象類別
InputStream是輸入位元組資料用的類,所以InputStream類別提供了3種重載的read方法.Inputstream類別中的常用方法:
(1) public abstract int read( ):讀取一個byte的數據,傳回值是高位補0的int型別值。若回傳值=-1說明沒有讀取到任何位元組讀取工作結束。
(2) public int read(byte b[ ]):讀取b.length個位元組的資料放到b數組中。傳回值是讀取的位元組數。此方法其實是呼叫下一個方法實作的
(3) public int read(byte b[ ], int off, int len):從輸入流中最多讀取len個位元組的數據,存放到偏移量為off的b數組中。
(4) public int available( ):傳回輸入流中可以讀取的位元組數。注意:若輸入阻塞,目前執行緒將被掛起,如果InputStream物件呼叫這個方法的話,它只會回傳0,這個方法必須由繼承InputStream類別的子類別物件呼叫才有用,
(5) public long skip(long n):忽略輸入流中的n個字節,回傳值是實際忽略的字節數, 跳過一些字節來讀取
(6) public int close( ) :我們在使用完之後,我們必須關閉我們開啟的串流.
主要的子類別:
1) 將一個檔案視為一個檔案所視為檔案所為的讀操作
2) ByteArrayInputStream:將記憶體中的一個緩衝區作為InputStream使用
3)StringBufferInputStream:將一個緩衝區物件當作InputStream
InputStreamStream 總是實作了主要概念的「主」使用
5) SequenceInputStream:把多個InputStream合併為一個InputStream
OutputStream提供了3個write方法來做資料的輸出,這個是和InputStream是相對應的。
1. public void write(byte b[ ]):將參數b中的位元組寫到輸出流。
2. public void write(byte b[ ], int off, int len) :將參數b的從偏移量off開始的len個位元組寫到輸出流。
3. public abstract void write(int b) :先將int轉換為byte型,低位元組寫入輸出流。
4. public void flush( ) : 將資料緩衝區中資料全部輸出,並清空緩衝區。
5. public void close( ) : 關閉輸出流並釋放與流相關的系統資源。
主要的子類別:
## 1) ByteArrayOutputStream:將資訊存入記憶體中的一個緩衝區中存入文件中 3) PipedOutputStream:實作了pipe的概念,主要在執行緒使用
4) SequenceOutputStream:將多個OutStream合併為一個OutStream
##read流結束的判斷:方法方法結束的判斷:方法方法()的傳回值為-1時;readLine()的傳回值為null時。
作用:以檔案為資料輸入來源的資料流。或者說是開啟文件,從文件讀資料到記憶體的類別。
使用方法(1)
File fin=new File("d:/abc.txt"); FileInputStream in=new FileInputStream( fin);
FileInputStream in=new FileInputStream(“d: /abc.txt”);
程式範例:
將InputFromFile.java的程式的內容顯示在顯示器上
導入 java.io.FileInputStream;
class TestFile {
static ## public static # #void main(String args[])拋出IOException{
# ##
new FileInputStream("InputFromFile.java");
int n=#512; byte buffer[]=new byte[n];
#0,n)!=-#while((rf.read(buffer,#0,n)!=-1)&&(n>0)){
緩衝) );
}
rf.close();
} catch(IOException IOe){
" ));#4.
檔案輸出流:FileOutputStream類別
FileOutputStream類別用於處理以檔案為資料目的輸出資料流;一個表示檔案名稱的字串,也可以是File或FileDescriptor物件。
方式1 : File f=new File(“d:/myjava/write.txt”);
FileOutputStream out=new FileOutputStream (f);
方式2:
#FileOutputStream out=new FileOutputStream(“ d:/myjava/write.txt");
##方式3:建構函式將FileDescriptor()物件作為其參數。
FileOutputStream f2=new FileOutputStream(fd);
##方式4:建構子將檔案名稱作為其第一個參數,將布林值第二參數。
【注意:(1)檔案中寫資料時,若檔案已經存在,則覆寫存在的檔案;(2)的讀取/寫入操作結束時,應呼叫close方法關閉流程。
程式範例:使用鍵盤輸入一段文章,將文章儲存在檔案write.txt中
導入 java.io.FileOutputStream;
public class TestFile {
## public
void main(String args[]) 拋出IOException{ ##
try {
##
位元組[n]; ## count = System.in.read(buffer);
FileOutputStream wf =
new FileOutputStream(wf.write(buffer,
0, count);wf.close();
// 當串流寫入作業結束時,呼叫close方法關閉流。 ;## } catch (IOException IOe) {
## 文件寫入錯誤!
}
#}
利用程式將檔案file1.txt複製到file2.txt中。
導入 java.io.FileOutputStream;
#public
#都##
public拋出 IOException {
File outFile =
new File(## FileOutputStream foutS =
##
int c;## while ((c = finS.read()) != -1) {
foutS.close();
## System.err.println("FileStreamsTest: " + e);
#6. 緩衝輸入輸出流 BufferedInputStream/ BufferedOutputStream
BufferedInputStream:當向緩衝流寫入資料時候,資料先寫到緩衝區,待緩衝區寫滿後,系統一次將資料傳送給輸出裝置。
BufferedOutputStream :當從向緩衝流讀取數據時候,系統先從緩衝區讀出數據,待緩衝區為空時,系統再從輸入設備讀取數據到緩衝區。
1)將檔案讀入記憶體:
將BufferedInputStream與FileInputStream相接
FileInputStream in= new FileInputStream( “file1.txt ” ); BufferedInputStream bin=new BufferedInputStream( in);
2)將內存寫入文件:
3)鍵盤輸入流讀到記憶體
將BufferedReader與標準的資料流相接
InputStreamReader sin=new InputStreamReader (System.in);
BufferedReader bin=new BufferedReader(sin);
public class ReadWriteToFile {
##
#
#### public static void main(String args[]) throws IOException {
# FileWriter out = new FileWriter("myfile.txt");
# out);
String s;) > 0) {
# }
} #}
程式說明:
從鍵盤讀入字符,並寫入到檔案中BufferedReader類別的方法:String readLine()
作用:讀取一行字串,以回車符為結束。
BufferedWriter類別的方法:bout.write(String s,offset,len)
作用:從緩衝區將字串s從offset開始,len長度的字串寫到某處。
8.字元流Writer/Reader
Java中字元是採用Unicode標準,一個字元是16位,即一個字元使用兩個位元組來表示。為此,JAVA中引入了處理字元的流。
# 用於讀取字元流的抽象類別。子類別必須實作的方法只有 read(char[], int, int) 和 close()。但是,多數子類別將重寫此處定義的一些方法,以提供更高的效率和/或其他功能。
1) FileReader :與FileInputStream對應:
(1)將檔案名稱作為字串:FileReader f=new FileReader(“c:/temp.txt”);
(2)建構子將File物件作為其參數。
File f=new file(“c:/temp.txt”);
FileDescriptor() fd=new FileDescriptor()
FileReader f2=new FileReader(fd);
# 1 (2) 將字元陣列作為輸入流:CharArrayReader(char[], int, int)
讀取字串,建構子如下: public StringReader(String s);
fIn##對應 3) StringReader :
與StringBufferInputStream對應
4) InputStreamReader inputstream is);
5) FilterReader: 允許過濾字元流
protected filterReader(Reader r); ## 物件接受為「並為其新增字元緩衝器,使用readline()方法可以讀取一行。 Public BufferReader(Reader r);
主要方法:
卷取的字元
(2) public int read(char cbuf[]) throws IOException; /*讀取一系列字元到陣列cbuf[]中,傳回值為實際讀取的字元的數量*/
(3) public abstract int read(char cbuf[],int off,int len) throws IOException;
寫入字元流的抽象類別。子類別必須實作的方法只有 write(char[], int, int)、flush() 和 close()。但是,多數子類別將重寫此處定義的一些方法,以提供更高的效率和/或其他功能。 其子類別如下:
#
1) FileWrite: 與FileOutputStream對應
將字元類型資料寫入文件,使用預設字元編碼和緩衝器大小。
Public FileWrite(file f);
2) chararrayWrite:與ByteArrayOutputStream對應 ,將字元緩衝器當作輸出。
Public CharArrayWrite();
3) PrintWrite:產生格式化輸出
public PrintWriter(outputstream os); public PrintWriter(outputstream os); public PrintWriter ## protected FilterWriter(Writer w);
5) PipedWriter:與PipedOutputStream對對應
(1) public void write(int c) throws IOException; //將整數值c的低16位元寫入輸出流
(2) publiccharid IOException; //將字元陣列cbuf[]寫入輸出流(3) public abstract void write(char cbuf[],int off,int len) throws IOIOIOCbuf[],int off,int len) throws IOIOC
索引為off的位置處開始的len個字元寫入輸出流
(4) public void write(String str) throws IOException; //將字串str中的字元寫入輸出流
(5) public void write(String str,int off,int len) throws IOException; //將字串str 中從索引off開始處的len個字元寫入輸出流 ) //刷空輸出流,並輸出所有被快取的位元組。 (7)close() 關閉流 public abstract void close() throws IOException
##3 .
##
InputStream和OutputStream類別處理的是位元組流,資料流中的最小單位是位元組(8個bit)
Reader與Writer處理的是字符流,在處理字元流時涉及了字元編碼的轉換問題
#import java.io.* ;
public class EncodeTest {
# private# private
private” #staticthrows IOException {
## in =new ByteArrayInputStream(buff);
卷while((data=in.read())!=-1) System.out.print(data+
" ");# System.out.println(); in.close(); }
void main(String args[]) throws IOException { # ("記憶體中採用unicode字元編碼:" );
char c=
#'好';'好';
'好'; '好';
'好'; ## int lowBit=c&
0xFF; ####int highBit=(c##0xFF00)>> ###################### System.out.println(###""+lowBit+###" "+highBit); ######### ###String s="好";
System.out.println("本地作業系統預設字元編碼:");
readBuff(s.getBytes());
System.out.println("採用UTF-8字元編碼:");
}
Writer類別能夠將內存中的Unicode字符轉換為其他編碼類型的字符,然後寫到輸出流中。
#9. IOException例外類別的子類
1.public class EOFException :
2.public class FileNotFoundException:
當檔案找不到時,拋出的例外。 ###3.public class InterruptedIOException:###### 當I/O作業中斷時,拋出這種類型的例外。 ###以上是Java輸入流輸出流的詳細內容。更多資訊請關注PHP中文網其他相關文章!