一.介紹
Java中對(duì)文件的操作是以流的方式進(jìn)行的。流是Java內(nèi)存中的一組有序數(shù)據(jù)序列。Java將數(shù)據(jù)從源(文件、內(nèi)存、鍵盤(pán)、網(wǎng)絡(luò))讀入到內(nèi)存中,形成了流,然后將這些流還可以寫(xiě)到另外的目的地(文件、內(nèi)存、控制臺(tái)、網(wǎng)絡(luò)),之所以稱為流,是因?yàn)檫@個(gè)數(shù)據(jù)序列在不同時(shí)刻所操作的是源的不同部分。
那么操作文件的流,我們稱之為文件件流,文件流不是若干個(gè)文件組成的流而是以文件流輸入輸出若要對(duì)文件進(jìn)行輸入輸出,若要對(duì)文件進(jìn)行輸入輸出。就必須通過(guò)文件流來(lái)實(shí)現(xiàn)。
二.知識(shí)點(diǎn)介紹
1、字節(jié)流
2、字符流
三.上課視頻對(duì)應(yīng)說(shuō)明文檔
回想之前寫(xiě)過(guò)的程序,數(shù)據(jù)都是在內(nèi)存中,一旦程序運(yùn)行結(jié)束,這些數(shù)據(jù)都沒(méi)有了,等下次再想使用這些數(shù)據(jù),可是已經(jīng)沒(méi)有了。那怎么辦呢?能不能把運(yùn)算完的數(shù)據(jù)都保存下來(lái),下次程序啟動(dòng)的時(shí)候,再把這些數(shù)據(jù)讀出來(lái)繼續(xù)使用呢? 其實(shí)要把數(shù)據(jù)持久化存儲(chǔ),就需要把內(nèi)存中的數(shù)據(jù)存儲(chǔ)到內(nèi)存以外的其他持久化設(shè)備(硬盤(pán)、光盤(pán)、U盤(pán)等)上。
當(dāng)需要把內(nèi)存中的數(shù)據(jù)存儲(chǔ)到持久化設(shè)備上這個(gè)動(dòng)作稱為輸出(寫(xiě))Output操作。
當(dāng)把持久設(shè)備上的數(shù)據(jù)讀取到內(nèi)存中的這個(gè)動(dòng)作稱為輸入(讀)Input操作。
因此我們把這種輸入和輸出動(dòng)作稱為IO操作。

1、字節(jié)流
1.1、一切均為字節(jié)
在數(shù)據(jù)傳輸過(guò)程中,一切數(shù)據(jù)(文本、圖像、聲音等)最終存儲(chǔ)的均為一個(gè)個(gè)字節(jié),即二進(jìn)制數(shù)字。所以數(shù)據(jù)傳輸過(guò)程中使用二進(jìn)制數(shù)據(jù)可以完成任意數(shù)據(jù)的傳遞。
我們向一個(gè)文件中存儲(chǔ)一定數(shù)據(jù)(一些數(shù)字),如果使用文本方式打開(kāi),則會(huì)以文本的方式解釋數(shù)據(jù)。如果以視頻的方式打開(kāi),則會(huì)以視頻的方式解釋數(shù)據(jù)。音頻、可行執(zhí)行文件等亦是如此。所以,在文件傳輸過(guò)程中,我們要時(shí)刻明確,傳輸?shù)氖冀K為數(shù)據(jù)。
1.2、字節(jié)輸出流
輸出流:OutputStream(抽象類):FileOutputStream(基本輸出流)
構(gòu)造方法:需要綁定IO資源
public FileOutputStream(String name)? 創(chuàng)建覆蓋寫(xiě)出對(duì)象
public FileOutputStream(String name,boolean append) 創(chuàng)建指定是否追加寫(xiě)出對(duì)象
其他方法: 寫(xiě)出時(shí),如果沒(méi)有該文件對(duì)象,會(huì)自動(dòng)創(chuàng)建文件對(duì)象

write(int n):輸出一個(gè)字節(jié);(使用int替代了byte)
write(byte[] b):輸出一個(gè)字節(jié)數(shù)組;
write(byte[] b, int off , int len):輸出字節(jié)數(shù)組的一部分;
flush():刷新此輸出流并強(qiáng)制寫(xiě)出所有緩沖的輸出字節(jié);
close(): 由于每個(gè)IO流都需要綁定一個(gè)IO資源,在使用時(shí),需要回收資源
1.3、FileOutputStream類
OutputStream有很多子類,其中子類FileOutputStream可用來(lái)寫(xiě)入數(shù)據(jù)到文件。
FileOutputStream類,即文件輸出流,是用于將數(shù)據(jù)寫(xiě)入 File的輸出流。
構(gòu)造方法
(1)FileOutputStream(File file):創(chuàng)建一個(gè)向指定File對(duì)象表示的文件中寫(xiě)入數(shù)據(jù)的文件輸出流。
(2)FileOutputStream(String name):創(chuàng)建一個(gè)向具有指定名稱的文件中寫(xiě)入數(shù)據(jù)的輸出文件流。
1.3.1、寫(xiě)出一個(gè)字節(jié)
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 字節(jié)輸出流?
* FileOutputStream(File file)? 創(chuàng)建一個(gè)向指定 File 對(duì)象表示的文件中寫(xiě)入數(shù)據(jù)的文件輸出流。
* FileOutputStream(String name)? 創(chuàng)建一個(gè)向具有指定名稱的文件中寫(xiě)入數(shù)據(jù)的輸出文件流。
*
*/
public class Demo2 {
public static void main(String[] args) throws IOException {
//創(chuàng)建 字節(jié)輸出流 對(duì)象.
FileOutputStream fos = new FileOutputStream("aaa.txt");
// 寫(xiě)出數(shù)據(jù)
fos.write(97);
// 關(guān)閉資源? , 必須做.
fos.close();?
}
}
1.3.2、FileOutputStream類寫(xiě)入數(shù)據(jù)到文件中
代碼示例:
public class FileOutputStreamDemo {
public static void main(String[] args) throws IOException {
//需求:將數(shù)據(jù)寫(xiě)入到文件中。
//創(chuàng)建存儲(chǔ)數(shù)據(jù)的文件。
File file = new File("c:\\file.txt");
//創(chuàng)建一個(gè)用于操作文件的字節(jié)輸出流對(duì)象。一創(chuàng)建就必須明確數(shù)據(jù)存儲(chǔ)目的地。
//輸出流目的是文件,會(huì)自動(dòng)創(chuàng)建。如果文件存在,則覆蓋。
FileOutputStream fos = new FileOutputStream(file);
//調(diào)用父類中的write方法。
byte[] data = "abcde".getBytes();
fos.write(data);
//關(guān)閉流資源。
fos.close();
}
}
1.4、給文件中續(xù)寫(xiě)和換行
我們直接new FileOutputStream(file)這樣創(chuàng)建對(duì)象,寫(xiě)入數(shù)據(jù),會(huì)覆蓋原有的文件,那么我們想在原有的文件中續(xù)寫(xiě)內(nèi)容怎么辦呢?
繼續(xù)查閱FileOutputStream的API。發(fā)現(xiàn)在FileOutputStream的構(gòu)造函數(shù)中,可以接受一個(gè)boolean類型的值,如果值true,就會(huì)在文件末位繼續(xù)添加。
構(gòu)造方法:
(1) FileOutputStream(File file,Boolean append):創(chuàng)建一個(gè)向指定File對(duì)象表示的文件中寫(xiě)入數(shù)據(jù)的文件輸出流。
(2) FileOutputStream(String name,boolean append):創(chuàng)建一個(gè)向具有指定name的文件中寫(xiě)入數(shù)據(jù)的輸出文件流。
給文件中續(xù)寫(xiě)數(shù)據(jù)和換行,代碼演示:
public class FileOutputStreamDemo2 {
public static void main(String[] args) throws Exception {
File file = new File("c:\\file.txt");
FileOutputStream fos = new FileOutputStream(file, true);
String str = "\r\n"+"fdm";
fos.write(str.getBytes());
fos.close();
}
}
1.4.1、寫(xiě)出多個(gè)數(shù)據(jù)&追加數(shù)據(jù)
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 1.創(chuàng)建流對(duì)象
* 2.寫(xiě)出數(shù)據(jù)
* 3.關(guān)閉流資源
*
* 當(dāng)使用流對(duì)象 ,寫(xiě)出數(shù)據(jù)到一個(gè)文件時(shí), 原來(lái)文件中的內(nèi)容會(huì)被清掉.新的數(shù)據(jù) 寫(xiě)出.
*
* 為了解決這個(gè)問(wèn)題.
* FileOutputStream(String name, boolean append) 創(chuàng)建一個(gè)向具有指定 name 的文件中寫(xiě)入數(shù)據(jù)的輸出文件流。
*/
public class Demo3 {
public static void main(String[] args) throws IOException {
//fun();?
//fun2();
//追加數(shù)據(jù)
//創(chuàng)建流對(duì)象
FileOutputStream? fos? =? new FileOutputStream("ccc.txt" , true );? // true 表示可以追加 .
//寫(xiě)出數(shù)據(jù)
fos.write(65);
// 關(guān)閉 資源
fos.close();
}
private static void fun2() throws FileNotFoundException, IOException {
//? * 1.創(chuàng)建流對(duì)象
FileOutputStream fos? = new FileOutputStream("ccc.txt");
//? * 2.寫(xiě)出數(shù)據(jù)
String s? = "hello? io " ;
byte[] bytes = s.getBytes();
fos.write(bytes);
//? * 3.關(guān)閉流資源
fos.close();
}
private static void fun() throws FileNotFoundException, IOException {
// 1.創(chuàng)建流對(duì)象
FileOutputStream fos = new FileOutputStream("bbb.txt");
// 2.寫(xiě)出數(shù)據(jù)
fos.write(98);
fos.write(99);
fos.write(100);
fos.write(101);
// 3.關(guān)閉流資源
fos.close();
}
}
1.5、字節(jié)輸入流
輸入流:InputStream(抽象類):FileInputStream(基本輸入流)
構(gòu)造方法:需要綁定IO資源
public FileInputStream(String name)
其他方法:讀取時(shí),返回?cái)?shù)據(jù)時(shí),使用int替代了byte
(1) abostract int read():從輸入流中讀取數(shù)據(jù)的下一個(gè)字節(jié)。
(2) int read(byte[] b):從輸入流中讀取一定數(shù)量的字節(jié),并將其存儲(chǔ)在緩沖區(qū)數(shù)組。
(3) lose(): 由于每個(gè)IO流都需要綁定一個(gè)IO資源,在使用時(shí),需要回收資源
1.6、FileInputStream類
InputStream有很多子類,其中子類FileInputStream可用來(lái)讀取文件內(nèi)容。
FileInputStream 從文件系統(tǒng)中的某個(gè)文件中獲得輸入字節(jié)。
構(gòu)造方法
(1)FileInputStream(file):通過(guò)打開(kāi)一個(gè)到實(shí)際文件的鏈接來(lái)創(chuàng)建一個(gè)FileInputStream,該文件通過(guò)文件系統(tǒng)中的File對(duì)象file指定。
(2)FileInputStream(String name):通過(guò)打開(kāi)一個(gè)到實(shí)際文件的鏈接來(lái)創(chuàng)建一個(gè)FileInputStream,該文件通過(guò)文件系統(tǒng)中的路徑名name指定。
1.7、FileInputStream類讀取數(shù)據(jù)read方法
abstract int read():從輸入流中讀取數(shù)據(jù)的下一個(gè)字節(jié)。
在讀取文件中的數(shù)據(jù)時(shí),調(diào)用read方法,實(shí)現(xiàn)從文件中讀取數(shù)據(jù)
1.7.1、讀取一個(gè)字節(jié)
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
*? 字節(jié)輸入流?
*? 構(gòu)造方法 FileInputStream(String name)
*?
*? 字節(jié)流在讀取數(shù)據(jù)的時(shí)候,字節(jié)類型的數(shù)據(jù)會(huì)被提升為int類型, 讀取到文件結(jié)尾,返回 -1.
*/
public class Demo {
public static void main(String[] args) throws IOException {
//fun();
//創(chuàng)建 字節(jié)輸入流?
FileInputStream fis? = new FileInputStream("bbb.txt");
// 讀取數(shù)據(jù)
int i = fis.read();
System.out.println((char) i);
i = fis.read();
System.out.println((char) i);
i = fis.read();
System.out.println((char) i);
i = fis.read();
System.out.println((char) i);
i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);
i = fis.read();
System.out.println(i);
// 關(guān)閉資源
fis.close();
}
private static void fun() throws FileNotFoundException, IOException {
//創(chuàng)建 字節(jié)輸入流?
FileInputStream fis? = new FileInputStream("aaa.txt");
// 讀取一個(gè)字節(jié)
int i = fis.read();
System.out.println(i);? // i 就表示你讀取到數(shù)據(jù).
char ch? =(char)i;? //? 基本的類型強(qiáng)制轉(zhuǎn)換.
System.out.println(ch);
// 關(guān)閉資源
fis.close();
}
}
1.7.2、循環(huán)讀取文件(讀取字節(jié))
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
*? 循環(huán)讀取文件.
*?
*? 1.創(chuàng)建輸入流對(duì)象
*? 2.讀取文件 read
*? 3.關(guān)閉資源
*/
public class Demo2 {
public static void main(String[] args) throws IOException {
//? *? 1.創(chuàng)建輸入流對(duì)象
FileInputStream fis? = new FileInputStream("ccc.txt");
//? *? 2.讀取文件 read
//定義 變量.保存讀取的字節(jié)數(shù)據(jù).
int? i? ;
while ((i=fis.read())!=-1) {
System.out.println((char)i);
}
//? *? 3.關(guān)閉資源
fis.close();
}
}
1.8、讀取數(shù)據(jù)read(byte[])方法
在讀取文件中的數(shù)據(jù)時(shí),調(diào)用read方法,每次只能讀取一個(gè),太麻煩了,于是我們可以定義數(shù)組作為臨時(shí)的存儲(chǔ)容器,這時(shí)可以調(diào)用重載的read方法,一次可以讀取多個(gè)字符。
int read(byte[] b):從輸入六種讀取一定數(shù)量的字節(jié),并將其存儲(chǔ)在緩沖區(qū)的數(shù)組b中。
1.8.1、使用字節(jié)數(shù)組讀取文件
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
* 使用字節(jié)數(shù)組讀取文件. 提高讀取的效率
*
* 使用數(shù)組讀取,每一個(gè)都把數(shù)據(jù)添加到數(shù)組中返回, 返回值 len ,表示當(dāng)前次讀取到的有效字符數(shù).
*/
public class Demo3 {
public static void main(String[] args) throws IOException {
// 創(chuàng)建輸入流對(duì)象
FileInputStream fis? = new FileInputStream("aaa.txt");
// 使用字節(jié)數(shù)組讀取.
byte[] b =? new byte[2];
int len? = fis.read(b);? // 每一次讀取, 會(huì)向 字節(jié)數(shù)組中,添加2個(gè)字節(jié)?
//打印 讀取的數(shù)據(jù)
System.out.print((char)b[0]);
System.out.println((char)b[1]);
System.out.println(len);
System.out.println("===========");
len? = fis.read(b);
System.out.print((char)b[0]);
System.out.println((char)b[1]);
System.out.println(len);
System.out.println("===========");
len = fis.read(b);
System.out.print((char)b[0]);
System.out.println((char)b[1]);
System.out.println(len);
// 關(guān)閉資源
fis.close();
}
}
1.8.2、len有效字節(jié)數(shù)組(復(fù)制文本文件)
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
*? len 有效字節(jié)數(shù)組 ,
*?
*/
public class Demo4 {
public static void main(String[] args) throws IOException {
// 創(chuàng)建流對(duì)象?
FileInputStream fis? = new FileInputStream("aaa.txt");
FileOutputStream fos? = new FileOutputStream("aaa2.txt");
// 操作數(shù)據(jù)
byte[] b = new byte[2]; // 建議? 1024的整數(shù)倍. 2,4, 8 .
int len; // 有效字節(jié) 數(shù).如果是文件結(jié)尾 返回 -1?
while (( len? = fis.read(b))!=-1) {
fos.write(b , 0 , len);? // b表示存數(shù)據(jù)的數(shù)組, 0表示開(kāi)始的位置, len有效字符個(gè)數(shù)
}
// 關(guān)閉資源
fos.close();
fis.close();
}
}
1.8.3、字節(jié)數(shù)組復(fù)制圖片文件
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
*? 邊讀邊寫(xiě),復(fù)制文本文件.
*?
*? 1.創(chuàng)建流對(duì)象. 輸入和輸出流
*? 2.操作數(shù)據(jù) . 讀取數(shù)據(jù)和寫(xiě)出數(shù)據(jù)
*? 3.關(guān)閉資源 . 關(guān)兩個(gè)流.
*/
public class Demo {
public static void main(String[] args) throws IOException {
// copy_txt();
// copy_pic();
// copy_pic2();
// 創(chuàng)建 流對(duì)象
FileInputStream fis? = new FileInputStream("hi.jpg");
FileOutputStream fos? = new FileOutputStream("hi2.jpg");
// 讀寫(xiě)數(shù)據(jù), 使用 數(shù)組 .
byte[] b? = new byte[1024];
int len ;?
// 循環(huán)讀取
while ((len = fis.read(b))!=-1) {
fos.write(b, 0, len);
}
// 關(guān)閉資源
fos.close();
fis.close();
System.out.println("高效復(fù)制完畢");
}
private static void copy_pic2() throws FileNotFoundException, IOException {
FileInputStream fis = new FileInputStream("hi.jpg");
FileOutputStream fos = new FileOutputStream("hi_copy.jpg");
int b;
while ((b = fis.read()) != -1) {
fos.write(b);
}
fos.close();
fis.close();
System.out.println("復(fù)制圖片完畢");
}
private static void copy_pic() throws FileNotFoundException, IOException {
FileInputStream fis = new FileInputStream("aa.jpg");
FileOutputStream fos = new FileOutputStream("aa_copy.jpg");
int b;
while ((b = fis.read()) != -1) {
fos.write(b);
}
fos.close();
fis.close();
System.out.println("復(fù)制圖片完畢");
}
private static void copy_txt() throws FileNotFoundException, IOException {
// 創(chuàng)建流對(duì)象
FileInputStream fis = new FileInputStream("ccc.txt");
FileOutputStream fos = new FileOutputStream("E:\\ccc.txt");
// 操作數(shù)據(jù)
int i;
// 讀取數(shù)據(jù)
while ((i = fis.read()) != -1) {
// 寫(xiě)出數(shù)據(jù)
fos.write(i);
}
// 關(guān)閉資源 . 后開(kāi)先關(guān), 先開(kāi)后關(guān).
fos.close();
fis.close();
System.out.println("復(fù)制文件完畢");
}
}
1.9、字節(jié)流練習(xí)
1.9.1、復(fù)制文件
原理;讀取一個(gè)已有的數(shù)據(jù),并將這些讀到的數(shù)據(jù)寫(xiě)入到另一個(gè)文件中。

代碼示例:
public class CopyFileTest {
public static void main(String[] args)throws IOException {
//1,明確源和目的。
File srcFile = new File("c:\\YesDir\test.JPG");
File destFile = new File("copyTest.JPG");
//2,明確字節(jié)流 輸入流和源相關(guān)聯(lián),輸出流和目的關(guān)聯(lián)。
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
//3,使用輸入流的讀取方法讀取字節(jié),并將字節(jié)寫(xiě)入到目的中。
int ch = 0;
while((ch=fis.read())!=-1){
fos.write(ch);
}
//4,關(guān)閉資源。
fos.close();
fis.close();
}
}
上述代碼輸入流和輸出流之間是通過(guò)ch這個(gè)變量進(jìn)行數(shù)據(jù)交換的。
上述復(fù)制文件有個(gè)問(wèn)題,每次都從源文件讀取一個(gè),然后在寫(xiě)到指定文件,接著再讀取一個(gè)字符,然后再寫(xiě)一個(gè),一直這樣下去。效率極低。
1.9.2、臨時(shí)數(shù)組方式復(fù)制文件
上述代碼復(fù)制文件效率太低了,并且頻繁的從文件讀數(shù)據(jù),和寫(xiě)數(shù)據(jù),能不能一次多把文件中多個(gè)數(shù)據(jù)都讀進(jìn)內(nèi)容中,然后在一次寫(xiě)出去,這樣的速度一定會(huì)比前面代碼速度快。
public class CopyFileByBufferTest {
public static void main(String[] args)throws IOException {
File srcFile = new File("c:\\YesDir\test.JPG");
File destFile = new File("copyTest.JPG");
// 明確字節(jié)流 輸入流和源相關(guān)聯(lián),輸出流和目的關(guān)聯(lián)。
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
//定義一個(gè)緩沖區(qū)。
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len);// 將數(shù)組中的指定長(zhǎng)度的數(shù)據(jù)寫(xiě)入到輸出流中。
}
// 關(guān)閉資源。
fos.close();
fis.close();
}
}
2、字符流
2.1、方便程序員的IO流
在IO開(kāi)發(fā)過(guò)程中,我們傳輸最頻繁的數(shù)據(jù)為字符,而以字節(jié)方式傳輸字符需要每次將字符串轉(zhuǎn)換成字節(jié)再處理,而且也喪失了程序員對(duì)數(shù)據(jù)內(nèi)容的判斷(因?yàn)槌绦騿T只認(rèn)識(shí)字符,不認(rèn)識(shí)字節(jié))。所以,為了讓程序員方便對(duì)字符進(jìn)行操作,Java提供了專門以字符作為操作單位的類——字符流,其底層仍然為字節(jié)流。
顯然,字符流只能操作字符,無(wú)法操作其他數(shù)據(jù),如聲音、視頻等。
2.2、字符輸出流FileWirter
既然有專門用于讀取字符的流對(duì)象,那么肯定也有寫(xiě)的字符流對(duì)象,查閱API,發(fā)現(xiàn)有一個(gè)Writer類,Writer是寫(xiě)入字符流的抽象類。其中描述了相應(yīng)的寫(xiě)的動(dòng)作。
(1)void write(char[] cbuf):寫(xiě)入字符數(shù)組;
(2)abstract void write(char[] cbuf,int off,int len):寫(xiě)入字符數(shù)組的某一部分;
(3)void write(int c):寫(xiě)入單個(gè)字符;
(4)void write(String str):寫(xiě)入字符串;
(5)void write(String str,int off,int len):寫(xiě)入字符串的某一部分。
2.3、FileWriter類
查閱FileOutputStream的API,發(fā)現(xiàn)FileOutputStream 用于寫(xiě)入諸如圖像數(shù)據(jù)之類的原始字節(jié)的流。要寫(xiě)入字符流,請(qǐng)考慮使用 FileWriter。
打開(kāi)FileWriter的API介紹。用來(lái)寫(xiě)入字符文件的便捷類。此類的構(gòu)造方法假定默認(rèn)字符編碼和默認(rèn)字節(jié)高效區(qū)大小都是可接受的。
構(gòu)造方法
(1)FileWriter(File file):根據(jù)給定的File對(duì)象構(gòu)造一個(gè)FileWriter對(duì)象。
(2)FileWriter(File file,Boolean append):根據(jù)給定的File對(duì)象構(gòu)造一個(gè)FileWriter對(duì)象。
(3)FileWriter(String fileName):根據(jù)給定的文件名構(gòu)造一個(gè)FileWriter對(duì)象。
(4)FileWriter(String filename,Boolean append):根據(jù)給定的文件名以及指示是否附加寫(xiě)入數(shù)據(jù)的boolean值來(lái)構(gòu)造FileWrter對(duì)象。
2.4、FileWirter寫(xiě)數(shù)據(jù)
構(gòu)造方法
(1)FileWriter(String fileName) 傳遞一個(gè)文件名稱
成員方法
(1)void write(String str):往文件中寫(xiě)入一個(gè)字符串。
(2)void flush() 刷新該流的緩沖,把內(nèi)存緩沖區(qū)中的數(shù)據(jù)刷新到文件中。
(3)void close():關(guān)閉此流,但要先刷新它。
輸出流寫(xiě)數(shù)據(jù)的步驟:
(1)創(chuàng)建輸出流對(duì)象
(2)調(diào)用輸出流對(duì)象的寫(xiě)數(shù)據(jù)的方法
(3)釋放資源
2.5、FileWriter寫(xiě)入中文到文件中
寫(xiě)入字符到文件中,先進(jìn)行流的刷新,再進(jìn)行流的關(guān)閉。
public class Demo01FileWriter {
public static void main(String[] args)throws
IOException {//創(chuàng)建輸出流對(duì)象
FileWriter fw = new FileWriter("d:\\a.txt");
/*
* 創(chuàng)建輸出流對(duì)象做了哪些事情:
*? A:調(diào)用系統(tǒng)資源創(chuàng)建了一個(gè)文件
*? B:創(chuàng)建輸出流對(duì)象
*? C:把輸出流對(duì)象指向文件
*/
//調(diào)用輸出流對(duì)象的寫(xiě)數(shù)據(jù)的方法
//寫(xiě)一個(gè)字符串?dāng)?shù)據(jù)
fw.write("IO流你好");
//數(shù)據(jù)沒(méi)有直接寫(xiě)到文件,其實(shí)是寫(xiě)到了內(nèi)存緩沖區(qū)
fw.flush();
//釋放資源
//通知系統(tǒng)釋放和該文件相關(guān)的資源
fw.close();
//while(true) {}
}
}
2.6、FileWriter寫(xiě)數(shù)據(jù)路徑問(wèn)題及關(guān)閉和刷新方法的區(qū)別
2.6.1、路徑:
(1)相對(duì)路徑:相對(duì)當(dāng)前項(xiàng)目而言的,在項(xiàng)目的根目錄下(a.txt)
(2)絕對(duì)路徑:以盤(pán)符開(kāi)始的路徑(d:\\a.txt)
2.6.2、close()和flush()方法的區(qū)別:
(1)abstract void close():關(guān)閉此流,但是要先刷新他。關(guān)閉資源,但在關(guān)閉前會(huì)將高效區(qū)中的數(shù)據(jù)先刷新到目的地,否則丟失數(shù)據(jù),然后在關(guān)閉流。流不可以使用。如果寫(xiě)入數(shù)據(jù)多,一定要一邊寫(xiě)一邊刷新,最后一次可以不刷新,由close完成刷新并關(guān)閉。
(2)abstract void flush():刷新該流的緩沖。將流中的高效區(qū)高效的數(shù)據(jù)刷新到目的地中,刷新后,流還可以繼續(xù)使用。
代碼示例:
public class Demo02FileWriter {
public static void main(String[] args)throws IOException {
//創(chuàng)建輸出流對(duì)象
//FileWriter fw = new FileWriter("d:\\a.txt");
FileWriter fw = new FileWriter("a.txt");
//調(diào)用輸出流對(duì)象的寫(xiě)數(shù)據(jù)方法,并刷新緩沖區(qū)
fw.write("helloworld");
fw.flush();
fw.write("java");
fw.flush();
//釋放資源
fw.close();
//Stream closed
//fw.write("javaee");
//fw.flush();
}
}
2.7、FileWriter寫(xiě)數(shù)據(jù)的5個(gè)方法
(1)void write(String str):寫(xiě)一個(gè)字符串?dāng)?shù)據(jù)
(2)void write(String str,int index,int len):寫(xiě)一個(gè)字符串中的一部分?jǐn)?shù)據(jù), index:開(kāi)始索引,len:寫(xiě)幾個(gè)
(3)void write(int ch):寫(xiě)一個(gè)字符數(shù)據(jù),這里寫(xiě)int類型的好處是既可以寫(xiě)char類型的數(shù)據(jù),也可以寫(xiě)char對(duì)應(yīng)的int類型的值。'a',97
(4)void write(char[] chs):寫(xiě)一個(gè)字符數(shù)組數(shù)據(jù)
(5)void write(char[] chs,int index,int len):寫(xiě)一個(gè)字符數(shù)組的一部分?jǐn)?shù)據(jù), index:開(kāi)始索引,len:寫(xiě)幾個(gè)
代碼示例:
public class Demo03FileWriter {
public static void main(String[] args)throws IOException {
//創(chuàng)建輸出流對(duì)象
FileWriter fw = new FileWriter("b.txt");
//void write(String str):寫(xiě)一個(gè)字符串?dāng)?shù)據(jù)
fw.write("abcde");
//void write(String str,int index,int len):寫(xiě)一個(gè)字符串中的一部分?jǐn)?shù)據(jù), index:開(kāi)始索引,len:寫(xiě)幾個(gè)
fw.write("abcde",0,5);
fw.write("abcde",1,3);
//void write(int ch):寫(xiě)一個(gè)字符數(shù)據(jù),這里寫(xiě)int類型的好處是既可以寫(xiě)char類型的數(shù)據(jù),也可以寫(xiě)char對(duì)應(yīng)的int類型的值。'a',97
fw.write('a');
fw.write(97);
//void write(char[] chs):寫(xiě)一個(gè)字符數(shù)組數(shù)據(jù)
char[] chs = {'a','b','c','d','e'};
//fw.write(chs);
//void write(char[] chs,int index,int len):寫(xiě)一個(gè)字符數(shù)組的一部分?jǐn)?shù)據(jù), index:開(kāi)始索引,len:寫(xiě)幾個(gè)
fw.write(chs,0,5);
fw.write(chs,2,3);
//釋放資源
fw.close();
}
}
2.8、FileWriter寫(xiě)數(shù)據(jù)之換行和追加寫(xiě)
2.8.1、續(xù)寫(xiě)問(wèn)題
FileWriter(String fileName, boolean append)
構(gòu)造放中參數(shù)的作用:
第一個(gè)參數(shù):寫(xiě)入文件的目的地
第二個(gè)參數(shù):append作用
true:可以續(xù)寫(xiě)
false:不能續(xù)寫(xiě),覆蓋之前的文件
2.8.2、換行問(wèn)題
windows:\r\n
linux:\n
mac:\r
換行符可以寫(xiě)在第一個(gè)數(shù)據(jù)的結(jié)尾,也可以寫(xiě)在第二個(gè)數(shù)據(jù)的開(kāi)頭
2.9、字符輸入流FileReader
2.9.1、FileReader讀數(shù)據(jù)
構(gòu)造方法
(1)FileReader(String fileName) 傳遞要讀取的文件名稱
成員方法
(1)int read() 讀取單個(gè)字符并返回
(2)int read(char[] cbuf) 一次讀取一個(gè)字符數(shù)組的數(shù)據(jù),返回的是實(shí)際讀取的字符個(gè)數(shù)
輸入流讀文件的步驟:
(1)創(chuàng)建輸入流對(duì)象
(2)調(diào)用輸入流對(duì)象的讀數(shù)據(jù)方法
(3)釋放資源
代碼示例:
public class Demo01FileReader {
public static void main(String[] args) throws IOException {
//創(chuàng)建輸入流對(duì)象
//FileReader fr = new FileReader("fr.txt");
FileReader fr = new FileReader
("Demo01FileWriter.java");
//調(diào)用輸入流對(duì)象的讀數(shù)據(jù)方法
//int read():一次讀取一個(gè)字符
int ch;
/*
* while循環(huán)的條件表達(dá)式一共做了3件事情
* 1:fr.read() 讀取一個(gè)字符
* 2:ch=fr.read() 把讀取的字符賦值給ch
* 3:ch != -1 判斷ch是否為-1
*/
while((ch=fr.read())!=-1) {
//System.out.println(ch);
//System.out.println((char)ch);
System.out.print((char)ch);
}
//釋放資源
fr.close();
}
}
注意:如果構(gòu)造方法中的文件不存在,會(huì)拋異常
java.io.FileNotFoundException: fr.txt (系統(tǒng)找不到指定的文件。)
2.9.2 FileReader類
查閱FileInputStream的API,發(fā)現(xiàn)FileInputStream 用于讀取諸如圖像數(shù)據(jù)之類的原始字節(jié)流。要讀取字符流,請(qǐng)考慮使用 FileReader。
打開(kāi)FileReader的API介紹。用來(lái)讀取字符文件的便捷類。此類的構(gòu)造方法假定默認(rèn)字符編碼和默認(rèn)字節(jié)高效區(qū)大小都是適當(dāng)?shù)?/p>
構(gòu)造方法
(1)FileReader(File file):在各頂從中讀取數(shù)據(jù)的File的情況下創(chuàng)建一個(gè)新FileReader;
(2)FileReader(String fileName):在給定從中讀取數(shù)據(jù)的文件名的情況下創(chuàng)建一個(gè)新FileReader;
2.9.3、FileReader讀取包含中文的文件
使用FileReader讀取包含中文的文件
public class CharStreamDemo {
public static void main(String[] args)throws IOException {
//給文件中寫(xiě)中文
writeCNText();
//讀取文件中的中文
readCNText();
}
//讀取中文
public static void readCNText() throws IOException {
FileReader fr = new FileReader("D:\\test\\cn.txt");
int ch = 0;
while((ch = fr.read())!=-1){
//輸出的字符對(duì)應(yīng)的編碼值
System.out.println(ch);
//輸出字符本身
System.out.println((char)ch);
}
}
//寫(xiě)中文
public static void writeCNText() throws IOException {
FileOutputStream fos = new FileOutputStream("D:\\test\\cn.txt");
fos.write("a奮斗蒙教程".getBytes());
fos.close();
}
}
2.10、字符流:讀取文件,一次讀寫(xiě)一個(gè)字符
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/*
* 字符流? :讀取文本文件?
*
* 字符輸入流 Reader 的子類, FileReader .
*/
public class Demo {
public static void main(String[] args) throws IOException {
//fun();?
// 循環(huán)讀取
FileReader fr? = new FileReader("ddd.txt");
int c ;
while (( c = fr.read())!=-1) {
System.out.print((char)c);
}
fr.close();
}
private static void fun() throws FileNotFoundException, IOException {
//創(chuàng)建字符輸入流對(duì)象?
FileReader fr? = new FileReader("ddd.txt");
// 讀取數(shù)據(jù)
int c? = fr.read();? // 讀取一次,返回一個(gè)字符.
System.out.println((char)c);? //20320? 你
c = fr.read();
System.out.println((char)c); //22909? 好
c? = fr.read();
System.out.println(c);
// 關(guān)閉資源
fr.close();
}
}
2.11、復(fù)制文本文件: 一次讀寫(xiě)一個(gè)字符復(fù)制文本文件
操作步驟:
(1)創(chuàng)建FileReader對(duì)象,并且綁定數(shù)據(jù)源
(2)創(chuàng)建FileWriter對(duì)象,并且綁定數(shù)據(jù)目的地
(3)調(diào)用FileReader中讀取字符的方法read
(4)調(diào)用FileWriter中寫(xiě)入字符的方法write
(5)釋放資源
代碼示例:
public class Demo01CopyFile {
public static void main(String[] args)throws IOException {
//創(chuàng)建輸入流對(duì)象
FileReader fr = new FileReader("Demo01FileWriter.java");
//創(chuàng)建輸出流對(duì)象
FileWriter fw = new FileWriter("Copy.java");
//讀寫(xiě)數(shù)據(jù)
int ch;
while((ch=fr.read())!=-1) {
fw.write(ch);
}
//釋放資源
fw.close();
fr.close();
}
}
2.12、FileReader讀數(shù)據(jù)一次一個(gè)字符數(shù)組
int read(char[] cbuf):一次讀取一個(gè)字符數(shù)組的數(shù)據(jù),返回的是實(shí)際讀取的字符個(gè)數(shù)
public class Demo02FileReader {
public static void main(String[] args)throws IOException {
//創(chuàng)建輸入流對(duì)象
//FileReader fr = new FileReader("fr2.txt");
FileReader fr = new FileReader("FileWriterDemo.java");
//調(diào)用輸入流對(duì)象的讀數(shù)據(jù)方法
//int read(char[] cbuf):一次讀取一個(gè)字符數(shù)組的數(shù)據(jù),返回的是實(shí)際讀取的字符個(gè)數(shù)
char[] chs = new char[1024]; //這里可以是1024及其整數(shù)倍
int len;
/*
* while循環(huán)的條件表達(dá)式一共做了3件事情
* 1:fr.read(chs) 把數(shù)據(jù)讀取到數(shù)組中
* 2:len=fr.read(chs) 把讀取的有效個(gè)數(shù)賦值給len
* 3:len != -1 判斷讀取的有效個(gè)數(shù)是否為-1
*/
while((len=fr.read(chs))!=-1) {
System.out.print(new String(chs,0,len));
}
//釋放資源
fr.close();
}
}
2.13、FileReader讀取數(shù)據(jù)的兩種方式圖解

2.13.1、復(fù)制文本文件: 一次讀寫(xiě)一個(gè)字符數(shù)組復(fù)制文本文件
public class Demo02CopyFile {
public static void main(String[] args)throws IOException {
//創(chuàng)建輸入流對(duì)象
FileReader fr = new FileReader("Demo01FileWriter.java");
//創(chuàng)建輸出流對(duì)象
FileWriter fw = new FileWriter("Copy.java");
//讀寫(xiě)數(shù)據(jù)
char[] chs = new char[1024];
int len;
while((len=fr.read(chs))!=-1) {
fw.write(chs, 0, len);
}
//釋放資源
fw.close();
fr.close();
}
}