輸入/輸出(I/O)操作的例子包括:
- 創建和刪除文件
- 從一個文件或者網絡套接字中讀取內容,或者向其寫入內容
- 把對象序列化(或保存)到持久內存中,並且獲取保存的對象
使用過舊的File類就會發現他的很多方法都無法拋出異常,delete方法常常工作失敗但原因非常讓人費解,rename方法也無法在不同的操作系統上一致的工作。所以JDK引入了一組名爲NIO.2的包,作爲技術補充,這些新的類型和子包能在java.nio.file中找到。其中的Path接口用來取代java.io.File類,好在後者現在已經被廢棄了。
需要注意的是Files中對於讀取和寫入只支持較小的文件,所以對於較大的文件就需要使用一個流。流包括以下四種:InputStream,OutputStream,Reader和Writer。同時我們會遇到一些類來包裝這些流和在讀寫時緩存數據。當對流進行讀寫操作時要求必須是順序的,對於非順序的操作,可以使用java.io.RandomAccessFile或者java.nio.channels.SeekableByteChannel。
1.文件系統和路徑
在JAVA中的文件或者路徑是使用java.io.File對象表示的,但它有很多缺陷,建議使用java.nio.Path替代。常用的FileSystem類就是在後者中。下面介紹一點該類常用的函數。
FileSystem filesyatem = FileSyatem.getDefault();//返回當前文件系統
Path Path= Paths.get("/home/images");//創建一個Path實例
path.getName(0);//返回home
2.文件的讀寫
Files類提供了從一個小的二進制文件或文本文件讀寫內容的方法。readAllBytes和readAllLines分別中一個二進制文件和文本文件讀取內容。返回類型分別爲byte[] 和List<String>。
下面是一個實例:
Path path = Paths.get("C://speech.txt");
Charset charset = Charset.forName("US-ASCII");//當針對字節編碼和字節解碼的時候需要制定使用的字符集
String str1 = "String1";
String str2 = "String";
List<String> lines = Arrays.asList(str1,str2);
try{
Files.write(path,lines,charset);//寫入
}catch(Exception e){
e.printStackTrace();
}
//讀回
List<String> linesRead = null;
try{
linesRead = Files.readAllLines(path,charset);
}catch(Exception e){
e.printStackTrace();
}
if(linesRead!=null){
for(String str:linesRead)
System.out.print(str);
}
再次提醒,read和write方法自適用於較小的文件,大一點的使用流來替代。
3.輸入/輸出流
數據可以分爲二進制和字符,對應I/O流也分別有兩種
·Reader,從一個池中讀取字符的流
·Writer,向一個池中寫入數據的流
·InputStream,從一個池中讀取二進制數據的流
·OutputStream,向一個池寫入二進制數據的流。
使用流,個人受益很多的是他的方法,不管什麼數據源和目標都能實現。
4.讀二進制數據
從NIO.2之後,就可以調用Files.newInputStream從一個文件池獲取InputStream。下面是一個模板代碼:
Path path = ...;
try(InputStraem is = Files.newInputStream(path,StanderdOpenOption.READ);
BufferInputStream buffer = new BufferInputStream(is)){
...
}catch(Exception e){
...
}
由於InputStream實現了AutoCloseable,因此在try—catch語句中不需要顯式的關閉它。否者一定要用流的close方法來關閉流。
InputStream類中的的read方法一共有三種:
第一個無參數的是最好用的,他從InputStream中每次讀取一個字節,並且返回一個int型值,再把這個值強制轉換爲byte類型,結合while語句塊保持循環就可以讀取文件。
int i = inputStream.read();
while(i!=-1){
byte b = (byte)i;
...
i = inputStream.read();
}
如果inputStream1和inputStream2分別讀取兩個文件的流,通過下面代碼就可以比較兩個文件內容是否相同:
int n,m;
do{
n = inputstream1.read();
m = inputstream2.read();
if(n!=m){
return false;
}
}while(n!=-1)
return true;
5.寫二進制數據
介紹過了InputStream,同理OutputStream的相關內容類比即可,不在介紹。
下面展示一個複製文件的範例:
byte[] reads = new byte[1024];//存儲InputStream讀取的數據
try(InputStream is = Files.newInputStream(originPath,,StandardOpenOption.Read);
OutputStream os =Files.newOutputStream(destinationPath,,StandardOpenOption.CREATE)){
int i = is.read(reads);
while(i!=-1){
os.write(reads,0,i);
i = is.read(reads);
}
}catch(Exception e){
....
}