Java IO

IO (read write)

java的控制檯輸入由System.in完成.

 

Java提供了兩種類型的輸入輸出流:

1)      一種是面向字節的流,數據的處理是以字節爲基本單位

2)      一種是面向字符的流,用於字符數據的處理

 

 

按流的方向來分:

——輸入流:把外部輸入讀入當前程序所在的內存

——輸出流:把當前程序所在內存的數據輸出到外部

 

按流處理數據來分:

——字節流:處理的數據單元是字節(8bit) 適應性廣,功能強大

——字符流:處理的數據單元是字符。通常來說,它主要用於處理文本文件,它在處理文本文件時更方便。

 

按流的角色來分

——節點流:和一個IO的物理節點關聯,比如磁盤中的某個文件,網絡等等

——包裝流(處理流/過濾流):以節點爲基礎,包裝之後的得到的流,所有的包裝流都是在Filtxxx的過濾流的子類

 


 


 

 

 

文件操作

 

 

創建文件

文件創建函數 file.createNewFile()   創建文件的時候需要拋出異常。


 

 

 

boolean   canRead()        如果文件可讀,返回真,否則返回假

boolean   canWrite()       如果文件可寫,返回真,否則返回假

boolean   exists()                     判斷文件或目錄是否存在

boolean   createNewFile()        若文件不存在,則創建指定名字的空文件,並返回真,若不存在返回假

boolean   isFile()                       判斷對象是否代表有效文件

boolean   isDirectory()     判斷對象是否代表有效目錄

boolean   equals(File f)    比較兩個文件或目錄是否相同

string       getName()                    返回文件名或目錄名的字符串

string       getPath()                      返回文件或目錄路徑的字符串

long         length()                       返回文件的字節數,若 File 對象代表目錄,則返回 0

long         lastModified()     返回文件或目錄最近一次修改的時間

String[]    list()         將目錄中所有文件名保存在字符串數組中並返回,若 File 對象不是目錄返回 null

boolean  delete()    刪除文件或目錄,必須是空目錄才能刪除,刪除成功返回真,否則返回假

boolean  mkdir()      創建當前目錄的子目錄,成功返回真,否則返回假

boolean   renameTo(File newFile)   將文件重命名爲指定的文件名

 

File parent = new File("C:"+File.separator+"haha");

parent.mkdir();// 一次只能創建一個目錄

 

 

File parent = newFile("C:"+File.separator+"haha"+File.separator+"haha");

parent.mkdirs();// 一次可以創建多個目錄

 

 

File[] listFiles() 返回一個抽象路徑名數組,這些路徑名錶示此抽象路徑名錶示的目錄中的文件。

 

File 的特徵:只能訪問磁盤上文件和目錄。無法訪問文件的內容。訪問文件的內容需要使用IO

 

 

 

文件的隨機讀寫

RandomAccessFile類用於隨機文件的創建和訪問,使用這個類可以跳轉到文件的任意位置讀寫數據

 

RnadomAccessFile——隨機(任意)訪問文件

Random——想訪問文件的那個點,就訪問文件的哪個點(任意)

特徵:

A)     即可讀,又可寫,還可追加 RandomAccessFile它不會覆蓋原有的文件內容

B)      只能訪問文件!相當於DataInputStream DataOutputStream

 

RandomAccessFile類是Object類的直接子類

l  Public RandomAccessFile(Stringname, String mode)    指定隨機文件流對應的文件名

l  Public RandomAccessFile(File file,String mode)          file指定隨機文件流對象所對應的文件名

 

Note mode表示所創建的隨機讀寫文件的操作狀態

l  r”表示以只讀的方式打開文件

l  rw”表示以讀寫方式打開文件,使用該模式只用一個對象即可同事實現讀寫操作

 


 

 

 

RandomAccessFile 類與文件內容有關,但是此類有一個缺點就是說如果要跳轉,則需要數據的保存長度一致。

 

 

long length()                      返回文件長度

voidseek(long pos)    移動文件位置指示器,pos 指定從文件開頭的偏離字節數

int skipBytes(int n)     跳過 n 個字節,返回數爲實際跳過的字節數

int read()                   從文件中讀取一個字節,字節的高 24 位爲 0,若遇到文件結尾,返回-1

final byte readByte() 從文件中讀取帶符號的字節值

final charreadChar()           從文件中讀取一個 Unicode 字符

final voidwriteChar(inte c)         寫入一個字符,兩個字節

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

InputStream&& OutputStream

 

FileInputStream          從文件中讀取的輸入流

PipedInputStream      輸入管道

FilterInputStream       過濾輸入流

ByteArrayInputStream        從字節數組讀取的輸入流

SequenceInputStream        兩個或多個輸入流的聯合輸入流,按順序讀取

ObjectInputStream    對象的輸入流

LineNumberInputStream   爲文本文件輸入流附加行號

DataInputStream        包含讀取 Java 標準數據類型方法的輸入流

BufferedInputStream          緩衝輸入流

PushbackInputStream         返回一個字節並把此字節放回輸入流

 

 

void close()            關閉輸入流

void mark()             標記輸入流的當前位置

void reset()            將讀取位置返回到標記處

int read()                      從輸入流中當前位置讀入一個字節的二進制數據,以此數據爲低位字節,補足16位的整型量(0~255)後返回,若輸入流中當前位置沒有數據,則返回-1

int read(byte b[])      從輸入流中的當前位置連續讀入多個字節保存在數組中,並返回所讀取的字數

 

int read(byte b[], int off, int len)     從輸入流中當前位置連續讀len長的字節,從數組第off+1個元素位置處開始存放,並返回所讀取的字節數

 

int available()                       返回輸入流中可以讀取的字節數

long skip(long n)                           略過n個字節

long skip(long n)                           跳過流內的n個字符

booleanmarkSupported()             測試輸入數據流是否支持標記

 

 

 

 

 

// 創建一個OuputStream的基類並用FileOutputStream給其賦值

InputStream in=null;

in=new FileInputStream(file);

//聲明一個byte數組,用於接受內容

byteb[]= newbyte[1024];

// 從文件中讀數據

in.read(b);

System.out.println(newString(b));

// 關閉流FileInputStream

in.close();

 

 

 

 

 

 

 

 

 

 

 

OutputStream類是一個抽象類,JAVA中上述的4種類都是抽象類:抽象類必須通過子類實例化

OutputStream會根據實例化它的子類或對象不同,輸出的位置也不同。

 

 

FileOutputStream       寫入文件的輸出流

PipedOutputStream   輸出管道

FilterOutputStream    過濾輸出流

ByteArrayOutputStream    寫入字節數組的輸出流

ObjectOutputStream          對象的輸出流

DataOutputStream     包含寫Java標準數據類型方法的輸出流

BufferedOutputStream      緩衝輸出流

PrintStream                       包含print()println()的輸出流

 

 

 

 

void close()                                         關閉輸出流

void flush()                                         強制清空緩衝區並執行向外設輸出數據

void write(int b)                                          將參數b的低位字節寫入到輸出流

void write(byte b[])                    按順序將數組b[]中的全部字節寫入到輸出流

void write(byte b[],int off, int len)      按順序將數組b[]中第off+1個元素開始的len個數據寫入到輸出流

 

 

 

import java.io.*;

publicclass JavaStream {

    publicstaticvoidmain(String[] args) throws Exception

    {

       // TODOAuto-generated method stub

       // 首先創建文件

       File file= new File("f:\\demo.txt");

       // 創建一個OuputStream的基類並用FileOutputStream給其賦值

       OutputStream out=null;

       out = new FileOutputStream(file);

       String string="gaoshuo ai chen lin !";

            // 向文件中寫數據

       out.write(string.getBytes());

       // 關閉流FileOutputStream

       out.close();

    }

}

 

 

 

 

 

InputSteam&& OutputStream

 

InputStream&& OutputStream主要用來對字節流進行操作

主要的操作方式:

》用File類找到一個文件

》用File類的對象去實例化InputStreamOutputStream的子類的對象

》對文件進行讀/寫操作

》關閉文件

 

InputStreamOutputStream所操作的都是字節操作,所有的數據都要通過byte數組操作

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Reader&& Writer

harArrayReader         從字符數組讀取的輸入流

BufferedReader         緩衝輸入字符流

PipedReader      輸入管道

InputStreamReader   將字節轉換到字符的輸入流

FilterReader       過濾輸入流

StringReader      從字符串讀取的輸入流

LineNumberReader   爲輸入數據附加行號

PushbackReader        返回一個字符並把此字節放回輸入流

FileReader          從文件讀取的輸入流

 

void close()        關閉輸入流

void mark()         標記輸入流的當前位置

booleanmarkSupported()           測試輸入流是否支持 mark

int read()                                從輸入流中讀取一個字符

int read(char[] ch)                   從輸入流中讀取字符數組

int read(char[] ch, int off, int len)     從輸入流中讀 len 長的字符到 ch

boolean ready()          測試流是否可以讀取

void reset()        重定位輸入流

long skip(long n)         跳過流內的 n 個字符

 

    publicstaticvoidmain(String[] args) throws Exception

    {

       // 首先創建文件

       File file=new File("f:\\write.txt");

// 創建一個Reader的基類並用FileReader給其賦值

       Reader r=null;

       r=new FileReader(file);

       //聲明一個char數組,用於接受內容

       charb[]=newchar[500];

       // 從文件中讀數據

       r.read(b);

       System.out.println("Outputis :"+ newString(b));

       // 關閉流FileReader

       r.close();

    }

 

 

CharArrayWriter        寫到字符數組的輸出流

BufferedWriter          緩衝輸出字符流

PipedWriter       輸出管道

OutputStreamWriter          轉換字符到字節的輸出流

FilterWriter        過濾輸出流

StringWriter       輸出到字符串的輸出流

PrintWriter        包含 print() println()的輸出流

FileWriter           輸出到文件的輸出流

 

 

 

void close()                       關閉輸出流

void flush()                        將緩衝區中的數據寫到文件中

void writer(int c)                        將單一字符 c 輸出到流中

void writer(Stringstr)         將字符串 str 輸出到流中

void writer(char[]ch)         將字符數組 ch 輸出到流

void writer(char[]ch, int offset, int length)          將一個數組內自 offset 起到 length 長的字符輸出到流

 

 

FileWrite類是Write子類OutputStreamWriter類的子類,因此FileWriter類既可以使用Writer類的方法也可以使用OutputStreamWrite類的方法來創建對象。

 

在使用FileWriter類寫入文件時,必須先調用FileWriter()構造方法創建FileWrite類的對象,在調用write()方法。

FileWrite構造方法的格式爲:

public   FileWriter(String name);

//根據文件名創建一個可寫入的輸出流對象

publicFileWrite(String name, Boolean a);

//a爲真,數據將追加到文件後面

 

 

 

    publicstaticvoidmain(String[] args) throws Exception

    {

       // TODOAuto-generated method stub

       // 首先創建文件

       File file=new File("f:\\write.txt");

       // 創建一個Writer的基類並用FileOutputStream給其賦值

       Writer w=null;

       w=new FileWriter(file);

       String string="ssgaoai chen lin!";

        // 向文件中寫數據

       w.write(string);

       // 關閉流FileWriter

       w.close();

      }

 

 

 

 

 

 

Note:

 

Reader&&Writer 用於操作字符流

字符輸出時如果不關閉則無法將內容寫入到文件:

      根本原因是如果字符流不關閉則內存中的數據不會強制性的輸出到文件,即,字符流操作中使用了緩存,在關閉時會強制性的清空緩存,也可以使用flush()方法手工清空緩存。

 

字符流用到了緩存而字節流沒有用到緩存。

 

 

ByteArrayInputStream && ByteArrayOutStram&& CharArrayReader && CharArrayWrites

 

 

 

 

PipedOutputStream && PipedInputStream&&PipedReader&& PipedWriter

管道流:主要用於線程間的通信

 

 


 

StreamReader && StreamWriter

 

 

 

 

 

 

 

BufferredInputStream&&BufferedOutputStream&&BufferedRead&&BufferedWrite

緩衝流:

——外部存儲器的速度比內存的速度要慢,外部存儲器的讀寫與內存的讀寫不同步!!通過緩衝就可以解決這種不同步。

——用完流之後,別忘了調用flush(把緩衝中的內容刷入實際的節點)方法

——調用close()也可——系統會在關閉之前自動刷緩衝

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

FilterInputStream&&FilterOutputStream&&FilterRead&&FilterWriter

 

節點流直接與IO節點關聯

——IO節點有很多,鍵盤,網絡,文件,磁帶…..


過濾流,建立在節點流的基礎之上。

過濾流的好處:——消除底層節點之間的差異

——使用過濾流的方法執行IO更加便捷

 

FileOutputStream  ---->PrintStream

FileWrite  ----> PrintStream

 

InputStream --> InputStreamReader --->BuferedReader

如果已經知道要讀取的內容是字符內容,就可以按上面的方式轉換

 

 

 

 

 

FileInputStream(File file)

FileInputStream(FileDescriptor fdObj)

FileInputStream(String name)

通過打開一個到實際文件的連接來創建一個FileInputStream,該文件通過文件系統中的路徑名name指定。

 

 

 

 

DataInputStream && DataOutputStream

 

DataInputStreamDataOutputStream爲過濾流(建立在已有IO流的基礎之上)

——這兩個流增加一些特定的方法來讀取特定的數據。

 

 

DataInputStream(InputStream in)

DataOutputStream(OutputStream out)

 

public class DataInputStreamextends FilterInputStreamimplements DataInput

 

 

System.out && System.in

 

System.out把輸出送到缺省的顯示(通常是顯示器)

 

staticPrintStream   out “標準輸出流”

PrintStreamOutputStream類的子類.

 

系統輸出是將所有信息輸出到指定的輸出設備上----顯示器。

System.out本身是屬於PrintStream對象,而PrintStreamOutputStream子類,所以現在實際上可以利用System.outOutputStream類執行實例化操作

 

import java.io.*;

publicclass JavaOut {

    publicstaticvoidmain(String[] args) throws Exception

    {

       // TODOAuto-generated method stub

       OutputStream out=null;

       out= System.out;

       String string ="Thisis word will export by windows!";

       out.write(string.getBytes());

    }

}

 

         system.in 是一個專門用於從鍵盤輸入數據的文件流

                static InputStream   in  “標準輸入流”

 

使用System.inInputStream實例化之後,內容確實可以輸入了,但是程序存在以下兩個問題:

》輸入的內容長度受限制

》如果輸入的中文超過容量,則可能出現亂碼

 

import java.io.*;

publicclass JavaIn {

   publicstaticvoidmain(String[] args) throws Exception

    {

       // TODOAuto-generated method stub

       InputStream in=null;

       in=System.in;

       byteb[]=newbyte[10];  //長度受限

       intlen=in.read(b);

       in.close();

       System.out.println("讀入的數據流是:"+new String(b,0,len));

    }

}

 

 

 

 

 

重定向標準輸入輸出:

——System.in : 標準輸入。通常代表鍵盤

——System.out: 標準輸出。通常代表屏幕

System.setOut() ——可以將標準輸出重定向另一個輸出流。

System.setIn() ——可以將標準輸入重定向另一個輸入流。

 

Java虛擬機讀取其他進程的數據:

Java啓動其他進程:

Runtime實例.exec()——該方法的返回值是一個Process對象。

Process——代表一個進程。進程就是應用程序。

 

 

PrintStream/PrintWrite
public class PrintStreamextends FilterOutputStream

PrintStream/PrintWriter實際上是一個打印流, 打印流比普通的OuputStream/Writer 提供了更多了打印數據的方法:

 

PrintStream或者PrintWriter的創建需要使用 OutputStream流來進行創建

PrintWriter(OutputStreamout);   根據現有的OutputStream創建不帶自動刷新的PrintWriter

向屏幕寫:

import java.io.*;

publicclass JavaOut {

    publicstaticvoid main(String[]args) throws Exception

    {

       // TODOAuto-generated method stub

       PrintWriter writer=new PrintWriter(System.out); 

       String string ="Thisis word will export by windows!";

       writer.print(string);

       writer.println('\n');

       writer.println(100);

       writer.close();

            只有在流關掉以後才能將內容顯示在界面上

} }

Note:

   如果未執行writer.close(),那麼不會顯示輸出結果,也就是說PrintWriter類使用緩衝區,當執行close操作時,纔將打印的內容顯示的輸出給相應的對象。

 

 

 

 

 

 

 

 

 

 

向文件中去寫:

import java.io.*;

publicclass JavaOut {

    publicstaticvoidmain(String[] args) throws Exception

    {

       // TODOAuto-generated method stub

       File file = new File("f:\\writer.txt");

       PrintWriter writer=new PrintWriter(newFileWriter(file));  

       String string ="Thisis word will export by windows!";

       writer.print(string);

       writer.println('\n');

       writer.println(100);

       writer.close();

    }

}

 

 

BufferedReader類讀取文件

 

BufferedReader 類是用來讀取緩衝區中的數據。使用時必須創建FileReader類對象,在用該對象爲參數創建BufferedReader類的對象。BufferedReader類有兩個構造方法,其格式爲:

 

public BufferedReader(Reader in);//  創建緩衝區字符輸入流

public BufferedReader(Reader in, int size);  // 創建輸入流並設置緩衝區的大小

 

 

在輸入數據的時候更希望將全部輸入的數據一次性讀取進來,如果一次性讀取,則肯定不會出現亂碼。

即輸入的數據放入到一個緩存中: BufferReader.

 

import java.io.*;

publicclass JavaIn {

   publicstaticvoidmain(String[] args) throws Exception

    {

       // TODOAuto-generated method stub

       BufferedReader read=null;

       //準備從鍵盤中讀取數據

       read=newBufferedReader(newInputStreamReader(System.in));

         String str=null;

         str=read.readLine();

         System.out.println(str);

      

    }

}

 

 

字節流和字符流之間的轉換:

InputStreamReaderOutputStreamWriter,這兩個類是字節流和字符流之間轉換的類,InputStreamReader可以將一個字節流中的字節解碼生成字符。

InputStreamReader:是將輸入的內容由字節變爲字符

OutputStreamWriter:是將輸出的內容由字符轉化爲字節

OutputStreamWriter將寫入的字符編碼成字節後寫入一個字節流.

 


 

序列化 && ObjectInputStream && ObjectOutputStream

ObjectOutputStream(OutputStream out)

ObjectInputStream(InputStream in)

序列化—— java對象(內存)《————》二進制流  

{ 序列化只是序列化對象(或實例),並非序列化類,所以添加static 修飾的Field是不會被序列化 }

目的: 

A>    有些時候,需要把對象存儲到外部存儲器中持久保存。

B>    有些時候,需要把對象通過網絡傳輸。

 

可序列化的對象: Java要求可序列化的類實現下面任意兩個接口:

——Serializable: 該接口只是一個標記性的接口,實現該接口無需實現任何方法

——Externalizable : 該接口需要實現方法

 

ObjectOutputStream——負責把對象保存到二進制流中

對應的方法:public final void writeObject(Object obj)  throws IOException

ObjectInputStream——負責把二進制流恢復對象

對應的方法:public final Object readObject()throws IOException,

 

 

 

對象引用變量序列化機制:

A>    引用變量所引用類型的對象的所有屬性的都應該是可以序列化的

B>    序列化的底層機制:

1>    每序列化一個對象,都會給該對象設置一個編號

2>    如果程序第一次序列化某個對象。系統會真的將該對象序列化成二進制流

3>    如果要序列化的對象是之前已經序列化的。此時僅序列化一個編號

這種序列化機制, 就是爲了保存磁盤裏的二進制流與內存中的對象是對應的。

 

Transient——修飾符

                 用於修飾成員變量。而且只能修飾實例變量,不能與static同時使用

                 transient用於執行被修飾的Field不會被序列化

static修飾的是類變量——序列化機制負責序列化實例

static修飾的類變量存儲在類信息中,並不是存儲在對象裏。

——因此static修飾的類變量不會被序列化。

 

 

 

transient作用:對於一些敏感信息,比如銀行卡的賬號,密碼,就不應被序列化出來。此時可以使用transient來屏蔽這些信息。但將一些屬性完全阻止在序列化之外,有時候也並不完善。

此時可以藉助於定製序列化”, 可以對屬性進行一些加密。

自定義序列化機制,必須實現如下兩個方法:

privatevoid writeObject(java.io.ObjectOutputStream out)

      throws IOException

{…}

privatevoid readObject(java.io.ObjectInputStream in)

      throws IOException, ClassNotFoundException

{…}

版本號:

當類在經常使用的時候,有時候系統無法確定反序列化時的class文件是否還正確,建議顯示爲可序列化指定一個版本號 /* 即使不指定,系統默認也有一個版本號,但不穩定 */

 

Serialver.exe——專門用於查看本類的版本號

Serialver ——show:顯示圖形化界面


自定義版本號:

privatestaticfinallongserialVersionUID = 1L;

自定義的版本號的好處是:更加穩定。

只有當我們修改了類的定義的時候,可以由程序員顯示的更改該serialVersionUID


 

 

 

 

Java 1.7 && java NIO

傳統的java裏,只有一個File類,即代表文件,又代表目錄

Path ——接口代表一個與平臺無關的路徑提供大量的文件操作路徑

Paths——工具類(Arrays Objects Collections Paths)——工具類中的所有方法都是靜態的

Files——操作文件的工具類,提供大量的方法操作文件

 

 

Java IO 小結

 

 


 

 

 

 

面向字符的輸入流都是Reader的子類,層次結構如圖:

 

 

 

 

 

 

 

 

 


 


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