Java I/O
在Java數組,變量和對象中存儲數據是暫時的,為保證永久地保存數據,就需要將其保存在硬盤文件中,Java的I/O技術就可以將數據保存為硬盤的文本文件。在了解“流”之前,我們需要先來看什麽是計算機的內存和硬盤。
內存是電腦的數據存儲設備之一,用來存放正在運行的程序和數據,可直接與運算器及控制器交換信息。內存是計算機中重要的部件之一,它是與CPU進行溝通的橋梁。計算機中所有程序的運行都是在內存中進行的,其作用是用於暫時存放CPU中的運算數據,以及與硬盤等外部存儲器交換的數據。只要計算機在運行中,CPU就會把需要運算的數據調到內存中進行運算,當運算完成後CPU再將結果傳送出來。硬盤是計算機重要的外部存儲設備,計算機的操作系統、應用軟件、文檔、數據等,都可以存放在硬盤上。
知道了內存和硬盤的區別,來看“流”的概念。
上面這幅圖展示了我們平常下載東西的過程。相對於內存而言,“流”根據方向可以分為輸入流和輸出流,輸入流是進入內存的方向,輸出流是離開內存的方向。根據讀取數據的格式,可以將內存分為字節流和字符流,字節流是按字節方式讀取數據的,通常用來讀取圖片,聲音,視頻等二進制文件,而字符流是按字符格式進行讀取數據的,可以用來讀取純文本文件,比如我們電腦上的txt文件,像doc文檔是有格式的,是非純文本文件,就需要使用字節流來進行讀取。
Java中處理這些輸入輸出的類都放在java.io包中,所有的輸入類都是字節輸入類(InputStream)和字符輸入類(Reader)的子類,而所有的輸出類都是字節輸出類(OutputStream)和字符輸出類(Writer)的子類。
我們需要重點掌握的主要有以下16個類:
文件讀寫字節流字符流
FileInputStream
FileOutputStream
FileReader
FileWriter
帶緩存的讀寫字節流字符流
BufferedReader
BufferedWriter
BufferedInputStream
BufferedOutputStream
專門處理數據的字節流字符流
DataInputStream
DataOutputStream
讀取對象的字節流字符流
ObjectInputStream
ObjectOutputStream
轉換流(字節流轉換成字符流)
InputStreamReader
OutputStreamWriter
PrintWriter
PrintStream(標準的輸出流,默認輸出到控制臺)
Java輸入輸出流主要有InputStream,OutputStream, Reader和Writer四大類,下面通過這兩張圖來了解這四類中的子類的繼承關系。
接下來看InputStream類的基本讀取方法。看以下代碼:
import java.io.*;
public class FileInputStreamTest01{
public static void main(String[] args){
FileInputStream fis=null;
try{
//要讀取一個文件,先要給這個文件創建一個輸入流
//文件路徑
String filepath="abc.txt"; // 絕對路徑
//String filepath="F:\\bianchenglianxi\\java\\abc.txt"; // 相對路徑
fis=new FileInputStream(filepath);
//讀取文件
int i1=fis.read();
int i2=fis.read();
int i3=fis.read();
int i4=fis.read();
int i5=fis.read();
int i6=fis.read();
int i7=fis.read();
System.out.println(i1);
System.out.println(i2);
System.out.println(i3);
System.out.println(i4);
System.out.println(i5);
System.out.println(i6);
System.out.println(i7);
}catch(FileNotFoundException e){
e.printStackTrace();
s}
catch(IOException e){
e.printStackTrace();
}finally{
if(fis!=null){
try{
fis.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
}
編譯運行後輸出:
/*
97
98
99
100
101
102
103
*/
1.先導入包java.io.*;
2.要讀取一個文件,先要給這個文件創建一個輸入流,即FileInputStream fis=new FileInputStream(filepath); 其中filepath是要讀入的文件所在的路徑,可以是絕對路徑,也可以是相對路徑。
3.使用read()方法讀取文件。
4.處理異常時要註意,IOException的範圍比FileNotFoundException的範圍大,所以前者要寫在後面,或者直接catch IOException即可。
5.最後使用close()方法關閉文件。
以上就是基本的讀取文件的方法。看第二個程序,直接使用throws拋出異常。
import java.io.*;
public class FileInputStreamTest02{
public static void main(String[] args) throws Exception{
FileInputStream fis=new FileInputStream("abc.txt");
while(true){
int temp=fis.read();
if(temp==-1)break;
System.out.println(temp);
}
fis.read();
}
}
以上程序使用while循環讀取文件,因為是一個字節一個字節進行讀取,所以存在缺點,頻繁地訪問磁盤,傷害磁盤,並且訪問效率低。接下來看使用數組讀取文件的方法,看以下代碼:
import java.io.*;
public class FileInputStreamTest03{
public static void main(String[] args)throws Exception{
FileInputStream fis=new FileInputStream("abc.txt");
byte[] bytes=new byte[3];//每一次最多讀取三個字節
//int read(byte[] bytes); 該方法返回的int類型的值代表的是這次讀取了多少個字節
int i1=fis.read(bytes);
//將bytes數組轉換成字符串
System.out.println(new String(bytes)); //abc
int i2=fis.read(bytes);
System.out.println(new String(bytes)); //def
int i3=fis.read(bytes);
System.out.println(new String(bytes,0,i3)); //gef
System.out.println(i1); //3
System.out.println(i2); //3
System.out.println(i3); //1
fis.close();
}
}
編譯運行後輸出:
/*
abc
def
g
3
3
1
*/
1.數組讀取的方法為int read(byte[] bytes),讀取之前在內存中準備一個數組,每次讀取多個字節存儲到byte數組中。
2.byte[] bytes=new byte[3]; 設置數組的大小,每次最多讀取三個字節。
3.int i1=fis.read(bytes); System.out.println(new String(bytes)); 將文件中的內容按字節讀取到數組中後,再將bytes數組轉換成字符串。
最後升級一下,看循環讀取文件內容,代碼如下:
/*
循環讀取
*/
import java.io.*;
public class FileInputStreamTest04{
public static void main(String[] args)throws Exception{
FileInputStream fis=new FileInputStream("abc.txt");
byte[] bytes=new byte[1024];
while(true){
int temp=fis.read(bytes);
if(temp==-1)break;
System.out.print(new String(bytes,0,temp));
}
fis.close();
}
}
編譯運行後輸出:
//abcdefg
Java I/O