Java基礎之文件的輸入輸出流操作


在介紹輸入輸出流之前,首先需要了解如何創建文件,創建文件夾以及遍歷文件夾等各種操作,這里面不在一一介紹,主要介紹的是文件的輸入輸出流操作。

在起初學習文件操作之前,總是喜歡將輸入輸出弄混淆,后來通過看一些書以及一些視頻,有了一些自己的心得體會,隨后介紹一下,以便在我以后忘記的時候可以溫習一下。

1.流的概念及分類

Java將所有傳統的流模型(類或抽象類),都放在了Java.io包中,用來實現輸入輸出的功能。

這里面我們將流分成兩種:輸入流和輸出流。

輸入流:只能從中讀取數據,而不能向其寫入數據。代表:InputStream(字節輸入流),Reader(字符輸入流)。

輸出流:只能向其寫入數據,而不能從中讀取數據。代表:OutputStream(字節輸出流),Writer(字符輸出流)。

流按照操作類型也可以分成兩種:

字節流 : 字節流可以操作任何數據,因為在計算機中任何數據都是以字節的形式存儲的 。它操作的數據單元是8位的字節。

字符流 : 字符流只能操作純字符數據,比較方便。它操作的數據單元是16位的字符。

在這個地方,我們需要弄清楚的就是什么是輸入,什么是輸出。如下圖所示:

 

從Java程序指向文件,這個過程我們稱為輸出或者寫入文件,從文件指向Java程序,這個過程我們稱為輸入或者讀出文件。

在輸入流和輸出流中,我們主要掌握4個流文件的操作:InputStream,OutputStream,Reader,Writer。這四個類都是抽象類,前兩個代表了字節的輸入輸出流,后兩個代表字符的輸入輸出流,當我們調用的時候通常使用他們的子類來實現我們的類方法。

 

2.字節輸出流(OutputStream)

字節輸出流它有以下幾個方法可以提供給它的子類使用(在輸入輸出流中,子類幾乎沒什么方法,都是調用父類的方法)

  • void close(): 關閉此輸出流並釋放與此流有關的所有系統資源。

  • void write(byte[] b): 將 b.length 個字節從指定的 byte 數組寫入此輸出流

  • void write(byte[] b, int off, int len) :將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此輸出流。

  • abstract void write(int b) : 將指定的字節寫入此輸出流。

由於OutputStream是抽象類,因此我們在向文件寫入(輸出)字節的時候,需要用到它的子類FileOutputStream,接下來通過使用上面的方法,來實現字節流的輸出操作。

關於FileOutputStream:

(1).寫入數據文件,通過使用父類的方法,調用子類的對象

(2).FileOutputStream構造方法:

  • 作用:綁定輸出的輸出目的

  • FileOutputStream(File file)

    • 創建一個向指定 File 對象表示的文件中寫入數據的文件輸出流。

  • FileOutputStream(File file, boolean append)

    • 創建一個向指定 File 對象表示的文件中寫入數據的文件輸出流,以追加的方式寫入。

  • FileOutputStream(String name)

    • 創建一個向具有指定名稱的文件中寫入數據的輸出文件流。

  • FileOutputStream(String name, boolean append)

    • 創建一個向具有指定 name 的文件中寫入數據的輸出文件流,以追加的方式寫入。

(3).流對象的使用步驟:

  1).創建流子類的對象,綁定數據目的。

  2).調用流對象的方法write寫

  3).close釋放資源

(4).注意事項:流對象的構造方法,可以用來創建文件,如果文件存在的情況下,直接覆蓋原文件。

接下來通過代碼來實現字節輸出流的方法:

(1).輸出單個字節

package IO_File;

import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo {

	public static void main(String[] args) throws IOException{
		// TODO Auto-generated method stub
		//創建字節輸出流的對象fos,並且指定了將直接寫到哪里
		FileOutputStream fos = new FileOutputStream("d:\\output.txt");
		//寫入一個字節,但是在文件中顯示的是ASCII表中對應的值。
		fos.write(97);
		//關閉系統資源
		fos.close();
	}

}		

最終結果:

 

 

(2).輸出字節數組

package IO_File;

import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputStreamDemo {

	public static void main(String[] args) throws IOException{
		// TODO Auto-generated method stub
		//創建字節輸出流的對象fos,並且指定了將直接寫到哪里
		FileOutputStream fos = new FileOutputStream("d:\\output.txt");
		byte[] b = {97,98,99,100,101,102,103};
		//流對象的方法write寫數據
		//將整個數組都寫入到文件中
		fos.write(b);
		//寫入了數組的一部分,從索引1的位置開始,寫入了兩個字節
		fos.write(b, 1, 2);
		//關閉資源
		fos.close();
	}

}		

最終結果:

 

 

 

3.字節輸入流(InputStream)

字節輸入流它有以下幾個方法可以提供給它的子類使用(在輸入輸出流中,子類幾乎沒什么方法,都是調用父類的方法)

  * abstract int read() : * 從輸入流中讀取數據的下一個字節,返回-1表示文件結束

  * int read(byte[] b) * 從輸入流中讀取一定數量的字節,並將其存儲在緩沖區數組 b 中。讀入緩沖區的字節總數,如果因為已經到達文件末尾而沒有更多的數據,則返回 -1。

  * int read(byte[] b, int off, int len) * 將輸入流中最多 len 個數據字節讀入 byte 數組。 * void close() * 關閉此輸入流並釋放與該流關聯的所有系統資源。

由於InputStream是抽象類,因此我們在從文件讀取(輸入)字節的時候,需要用到它的子類FileInputStream,接下來通過使用上面的方法,來實現字節流的輸入操作。

關於FileInputStream:

在使用FileInputStream創建對象的時候,我們也需要為這個類綁定數據源(我們要讀取的文件名)

FileInputStream的構造方法與上述的構造方法相似,里面的參數有兩種類型:File類型對象,String類型對象。

輸入流讀取文件的操作步驟:

(1).創建字節輸入流的子類對象

(2).調用讀取方法read讀取

(3).關閉資源

注意事項:read()方法每執行一次,就會自動的讀取下一個字節。它的返回值是讀取到的字節,如果沒有字節可以讀取了,那么返回-1。

下面用代碼來實現FileInputStream的操作

(1).按照每個字節進行讀取(效率相對低)

package IO_File;

import java.io.FileInputStream;
import java.io.IOException;

//字節輸入流
public class FileInputStreamDemo {

	public static void main(String[] args) throws IOException{
		FileInputStream fis = new FileInputStream("d:\\input.txt");
		//必須添加這個變量,直接使用fis.read作為輸出,因為每次執行read()方法的時候,讀取文件字節的指針都會向后移動一位。
		int hasRead = 0;
		//因為hasRead是每個字節的值,當為-1的時候,代表了整個文件都被讀取。
		while((hasRead = fis.read())!=-1){
			System.out.println(hasRead);
		}
		//關閉文件資源
		fis.close();
	}

}

最終結果:

文件中的數據:

 

 

 現在再Java程序中的數據:

(2).讀取字節數組

方法介紹:

  1).int read(byte[] b):從輸入流中讀取一定數量的字節,並將其存儲在緩沖區數組 b 中。讀入緩沖區的字節總數,如果因為已經到達文件末尾而沒有更多的數據,則返回 -1。

  2).int read(byte[] b,int off,int len):將輸入流中最多 len 個數據字節讀入 byte 數組。

代碼實現:

package IO_File;

import java.io.FileInputStream;
import java.io.IOException;

//字節輸入流
public class FileInputStreamDemo {

	public static void main(String[] args) throws IOException{
		FileInputStream fis = new FileInputStream("d:\\input.txt");
		//創建字節數組,相當於每次從文件中讀取1024個字節保存到這個數據中。這里面一般都寫1024
		byte[] b = new byte[1024];
		//必須添加這個變量,直接使用fis.read作為輸出,因為每次執行read()方法的時候,讀取文件字節的指針都會向后移動一位。
		int len = 0 ;
		//因為hasRead是每個字節的值,當為-1的時候,代表了整個文件都被讀取。
		while( (len = fis.read(b)) !=-1){
			System.out.print(len);
		}
		fis.close();
	}
}

最終的答案跟上述的結果相同,但是使用數組的執行效率比單個字節的效率高很多。

4.字符輸出流(Writer)

由於Writer也是一個抽象類,因此我們用它的子類FileWriter來實現字符流的輸出操作。

關於FileWriter:

(1).方法介紹:

  void write(int c):寫入單個字符。

  void write(String str):寫入字符串。

  void write(String str, int off, int len):寫入字符串的某一部分。

  void write(char[] cbuf):寫入字符數組。

  abstract void write(char[] cbuf, int off, int len):寫入字符數組的某一部分。

代碼實現:

package IO_File;

import java.io.FileWriter;
import java.io.IOException;

public class FileWriterDemo {

	public static void main(String[] args) throws IOException{
		// TODO Auto-generated method stub
		FileWriter fw = new FileWriter("d://filewriter.txt");
		fw.write("123");
		//必須要加fw.flush(),代表刷新,不加這個語句不能寫入到文件中
		fw.flush();
		fw.close();
	}

}

最終結果:

 

5.字符輸入流(Reader)

由於Reader也是一個抽象類,因此我們用它的子類FileReader來實現字符流的輸出操作。

 (1)方法介紹:

   int read() * 讀取單個字符

   int read(char[] cbuf) * 將字符讀入數組

   abstract int read(char[] cbuf, int off, int len) * 將字符讀入數組的某一部分。

 代碼實現:

package IO_File;

import java.io.FileReader;
import java.io.IOException;

public class FileReaderDemo {

	public static void main(String[] args) throws IOException{
		// TODO Auto-generated method stub
		FileReader fr = new FileReader("d://input.txt");
		int hasRead = 0;
		while((hasRead = fr.read())!=-1){
			System.out.print((char)hasRead);
		}
		fr.close();
	}

}

最終結果:

 

 字符流的輸入輸出與字節流的差不多,但是字符流只能操作文本文件,不能操作除了文本文件以外的文件,而字節流可以操作文本文件以及音樂,視頻等文件,因此在平時的IO流中,我們使用字節流的操作更多一些。

6.文件的復制操作。(這里面我使用字節流的方式實現)

文件的復制操作簡單的說就是將一個文件上的內容讀取出來,並且將讀取到的內容寫入到另一個文件上,因此在文件的復制操作中,需要我們使用文件的輸入和輸出流操作。

注意事項:在復制文件的過程中,我們需要先讀后寫。

代碼的實現方式如下:

package IO_File;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileCopy {

	public static void main(String[] args) throws IOException{
		// TODO Auto-generated method stub
		//文件復制,先讀后寫
		
		FileInputStream fis = new FileInputStream("d://input.txt");
		FileOutputStream fos = new FileOutputStream("d://1.txt");
		int hasRead = 0;
		while((hasRead = fis.read()) != -1){
			fos.write(hasRead);
		}
		
		fos.close();
		fis.close();
	}

}

最終結果,將input.txt文件中的數據復制到了1.txt文件中。

 

 

為了我們共同進步,我這里有計算機專業的各種視頻,

如果想要,關注我的公眾號:念流聲。私聊我,看到后給你連接(只放了一張圖片,視頻有很多,需要什么可以私聊問我,有的話就給你)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM