從屌絲到架構(gòu)師的飛越(IO流篇)-文件流

一.介紹

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();

}

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容