日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

JavaSE——IO(上)(File、字节流、字符流、转换流、打印流、缓存流)

發(fā)布時(shí)間:2024/7/23 java 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaSE——IO(上)(File、字节流、字符流、转换流、打印流、缓存流) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

第3節(jié) IO(上)

一、File類與文件基本操作

在程序中經(jīng)常需要用到文件的操作,Java有專門的類來進(jìn)行文件的操作——File類。

1.1 File類概述

它是對(duì)文件和目錄路徑名的抽象表示。 即它本身不是一個(gè)文件,只是一個(gè)抽象表示,一個(gè)用于操作文件的對(duì)象(實(shí)現(xiàn)后)。

用戶界面和操作系統(tǒng)使用依賴于系統(tǒng)的路徑名字符串來命名文件和目錄。此類提供了一個(gè)抽象的,與系統(tǒng)無關(guān)的分層路徑名視圖。

1.2 絕對(duì)路徑于相對(duì)路徑

  • 絕對(duì)路徑 :從盤符開始,是一個(gè)完整的路徑,例如:c://a.txt;

  • 相對(duì)路徑 :在Java代碼中是相對(duì)于項(xiàng)目目錄路徑 ,這是一個(gè)不完整的便捷路徑,在Java開發(fā)中很常用。

看一個(gè)例子就明白了:

package com.kaikeba.coreclasslibrary.io;import java.io.File;public class path {public static void main(String[] args) {File file1 = new File("c://a.txt");File file2 = new File("a.txt");System.out.println("file1的路徑:"+file1.getAbsolutePath());System.out.println("file2的路徑:"+file2.getAbsolutePath());} }結(jié)果如下: file1的路徑:c:\a.txt file2的路徑:E:\JAVAEE開發(fā)工程師\code\classcode\a.txt

其中項(xiàng)目的路徑就是E:\JAVAEE開發(fā)工程師\code\classcode。

1.3 File類字段

這邊的路徑分隔符和默認(rèn)名稱分隔符是為了適應(yīng)不同的os,因?yàn)樵诓煌膐s上它們是不一樣的,為了避免經(jīng)常修改這些,可以利用File類給出的這些字段,在不同的os上會(huì)給出相應(yīng)的分隔符,下面看一下Windows上的分隔符是什么:

System.out.println(File.pathSeparator); System.out.println(File.separator);結(jié)果如下: ; \

1.4 構(gòu)造方法

parent和child構(gòu)造的方法,parent是目錄,child是具體文件名。

1.5 方法

1、三個(gè)測(cè)試:

2、比較兩個(gè)抽象路徑名:

3、在該路徑下創(chuàng)建文件:存在則不新建

4、刪除文件:

5、判斷是否存在該文件:

6、得到絕對(duì)路徑:可以是File類或String字符串

7、得到文件或目錄名稱:

8、測(cè)試是否是絕對(duì)路徑、目錄、文件、隱藏文件:

9、返回文件的長度(大小):

10、列出該目錄下的所有文件或字符串路徑:

11、新建目錄或遞歸新建目錄

上述就是一些常用方法。

1.6 文件遍歷與文件過濾器

1.6.1 文件遍歷(充分利用File類的方法)

如何在一個(gè)路徑下找出所有的PDF文件?這就需要遍歷路徑下的所有文件和目錄,遇到目錄還要在進(jìn)目錄繼續(xù)遍歷:

代碼如下:

package com.kaikeba.coreclasslibrary.io;import java.io.File;public class listfiles {public static void main(String[] args) {File e = new File("e:\\");File[] files = e.listFiles();listFiles(files);}private static void listFiles(File[] files) {if(files != null && files.length > 0) {for(File file:files) {if(file.isFile()) {//文件if(file.getName().endsWith(".pdf")) {//找到了一個(gè)大于10M的PDF文件if(file.length()>10*1024*1024) {System.out.println(file.getAbsolutePath());}}}else {//文件夾,繼續(xù)遞歸遍歷File[] files2 = file.listFiles();listFiles(files2);}}}} }結(jié)果就是遍歷的所有在E盤下的PDF的路徑...

1.6.2 文件過濾器

上述遍歷的框架已經(jīng)有了,但是在判斷是否是我們要找的文件時(shí)if判斷是我們自己寫的,還有一種方法,雖然不常用,但是也可以了解。

listFiles方法的參數(shù)里有一個(gè)FileFilter類型的filefilter變量:

FileFilter是一個(gè)接口,只有一個(gè)抽象方法:

可以把判斷條件寫在accept里面,如果返回true就保存該文件,返回false就不保留該文件,例子如下:

package com.kaikeba.coreclasslibrary.io;import java.io.File; import java.io.FileFilter;public class filefilter2 {public static void main(String[] args) {File e = new File("e:\\");listFiles(e);}private static void listFiles(File file) {//1. 創(chuàng)建一個(gè)過濾器規(guī)則 并 描述規(guī)則//2. 通過文件獲取子文件夾File[] files = file.listFiles(new FileFilter() {@Overridepublic boolean accept(File pathname) {if(pathname.getName().endsWith(".pdf") || pathname.isDirectory()) {return true;}return false;}});if(files != null || files.length > 0) {for (File f : files) {if (f.isDirectory()) {listFiles(f);} else {System.out.println(f.getAbsolutePath());}}}} }返回結(jié)果如上述代碼一致。

二、流(輸入輸出)概述

計(jì)算機(jī)中的任何數(shù)據(jù)(文本,圖片,視頻,音樂等等)都是以二進(jìn)制形式存儲(chǔ)的。在數(shù)據(jù)傳輸時(shí),也都是以二進(jìn)制形式存儲(chǔ)的。后續(xù)學(xué)習(xí)的任何流,在傳輸時(shí)底層都是二進(jìn)制。

可以將數(shù)據(jù)傳輸?shù)牟僮?#xff0c;看做一種數(shù)據(jù)的流動(dòng)。按照流動(dòng)的方向,分為輸入Input和輸出Output。

Java中的IO操作主要指的是java.io包下的一些常用類的使用,通過這些類,對(duì)數(shù)據(jù)進(jìn)行讀取(輸入Input)和寫出(Output)。

IO流的分類:

  • 按照流的方向來分,可以分為:輸入流和輸出流

  • 按照流動(dòng)的數(shù)據(jù)類型來分,可以分為:字節(jié)流和字符流

字節(jié)流:

  • 輸入流:InputStream

  • 輸出流:OutputStream

字符流:

  • 輸入流:Reader

  • 輸出流:Writer

三、字節(jié)流

3.1 字節(jié)輸出流OutputStream類

3.1.1 OutputStream類概述

此抽象類是表示輸出字節(jié)流的所有類的超類,輸出流接收輸出字節(jié)并將它們發(fā)送到某個(gè)接收器。它的實(shí)現(xiàn)子類最常用的就是:FileOutputStream類。

方法:

1、關(guān)閉輸出流:

2、刷新緩存,強(qiáng)制寫出:

3、寫出操作:將字節(jié)數(shù)組或字節(jié)寫出

3.1.2 FileOutputStream類

是OutputStream類最常用的一個(gè)實(shí)現(xiàn)類。

構(gòu)造方法:

指定要輸出寫入的文件對(duì)象或String路徑(文件不存在會(huì)自動(dòng)創(chuàng)建),append表示是否追加寫入,true為追加模式,false為清空內(nèi)容從頭寫入。

方法: 基本就是使用OutPutStream類的方法。

看個(gè)例子:

package com.kaikeba.coreclasslibrary.io;import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;public class outputstream {public static void main(String[] args) throws IOException {//FileOutputStreamFileOutputStream fos = new FileOutputStream("a.txt"); // byte[] bytes = {65,66,67,68,69}; // fos.write(65);byte[] bytes = "ABCDEF".getBytes(); // fos.write(bytes);fos.write(bytes, 1, 2);fos.close();System.out.println("已經(jīng)寫出");} }結(jié)果為: BC

3.2 字節(jié)輸入流InputStream類

3.2.1 InputStream類概述

此抽象類是表示輸入字節(jié)流的所有類的超類。最常見的子類是FileInputStream類。

方法:

1、關(guān)閉輸入流:

2、讀取下一個(gè)字節(jié):

3、讀取一些字節(jié):

4、讀取一些字節(jié),并指定開始位置和讀取個(gè)數(shù):

注意: 讀取的方法返回的都是讀取到的有效字節(jié)的個(gè)數(shù)如果已經(jīng)到文件末尾,將會(huì)返回-1 。

5、其他一些讀取方法:

6、跳過并丟棄輸入流的n字節(jié)數(shù)據(jù):

3.2.2 FileInputStream類

是InputStream類最常用的一個(gè)子類。

構(gòu)造方法:

給定要讀取的文件。

方法:

看一個(gè)例子:

首先在a.txt文件中寫有Hello InputStream的內(nèi)容。下面來將其文件中的內(nèi)容讀取到程序中:

package com.kaikeba.coreclasslibrary.io;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream;public class inputstream {public static void main(String[] args) throws IOException {//FileInputStreamInputStream fis = new FileInputStream("a.txt");while(true) {byte b = (byte)fis.read();//b如果為-1,表示已經(jīng)讀取到文件末尾,讀取完畢if(b == -1) {break;}System.out.print((char)b);}} }結(jié)果為: Hello InputStream

但是這種方式每次只讀取一個(gè)字節(jié),需要很多次讀取(read)操作,與文件的連接次數(shù)太多會(huì)拖慢程序的速度,所以可以使用read的另一個(gè)方法:

package com.kaikeba.coreclasslibrary.io;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream;public class inputstream {public static void main(String[] args) throws IOException {//FileInputStreamInputStream fis = new FileInputStream("a.txt");//推薦下面這種方式讀取,因?yàn)樽x取的次數(shù)較少byte[] bytes = new byte[10];int len = fis.read(bytes);System.out.println(new String(bytes,0,len));len = fis.read(bytes);System.out.println(new String(bytes,0,len));len = fis.read(bytes);System.out.println(len);fis.close();} }結(jié)果如下: Hello Inpu tStream -1

用一個(gè)字節(jié)數(shù)組來接收讀取到的固定長度的數(shù)據(jù),但是要注意,讀到最后,如果不滿10個(gè)字節(jié)了,那么返回的將不是希望的結(jié)果,因?yàn)槭菍⑿伦x取到的覆蓋數(shù)組,未滿10個(gè)最后幾個(gè)后面將不會(huì)被覆蓋,即多出幾個(gè)沒用的字節(jié)。

解決:按照上述的寫法,將成功讀取到的字節(jié)個(gè)數(shù)接收,并用String的bytes數(shù)組指定長度的構(gòu)造方法來輸出。

優(yōu)點(diǎn):這樣大大減少了連接文件的次數(shù),加速了程序的運(yùn)行。

3.2.3 字節(jié)流讀取文字

如果將上述a.txt中的內(nèi)容換成中文,比如 鋤禾日當(dāng)午,汗滴禾下土 ,再來看上述代碼的輸出:

鋤禾日� ��午,� �滴禾下

這并不是亂碼,因?yàn)橹形木幋a一般不是一個(gè)字節(jié)來表示一個(gè)字,所以它10個(gè)字節(jié)可能讀到的是3個(gè)半字,那半個(gè)字是無法恢復(fù)的,它比亂碼更加可怕 ,這就是字節(jié)流的缺點(diǎn)所在,后續(xù)學(xué)習(xí)字符流就是專門解決讀取文字的問題。

四、字符流

字符流與字節(jié)流的區(qū)別就是字節(jié)流是一個(gè)字節(jié)一個(gè)字節(jié)的傳輸,但是字符流不太一樣,雖然內(nèi)部還是傳輸?shù)淖止?jié),但是因?yàn)橐粋€(gè)字符,比如一些非英文文字,需要幾個(gè)字節(jié)來表示一個(gè)字符,所以它會(huì)一次讀或?qū)懸粋€(gè)字符,這樣就可以避免3.2.3出現(xiàn)的問題。

4.1 字符輸出流Writer類

4.1.1 Writer類概述

用于寫入字符流的抽象類。最常用的子類為OutputStreamWriter下的FileWriter。其中OutputStreamWriter后續(xù)介紹。

方法:

比較常用的有:

1、append:將字符或序列追加到此Writer,注意它的返回類型為Writer,即追加完后的文件自己。

其實(shí)它內(nèi)部調(diào)用的還是write方法,但是write方法沒有返回,這就使得append方法可以連續(xù)操作(當(dāng)然用write也可以達(dá)到一樣的效果)。

2、close:關(guān)閉流,關(guān)閉之前先刷新緩存

3、flush:刷新緩存,如果不刷新,內(nèi)容是寫在緩存區(qū)的,還沒有真正寫入文件:

close方法中已經(jīng)調(diào)用了flush,這里我們不使用close,只看使用flush和不使用flush的區(qū)別:

目前b.txt是空的,下面調(diào)用:

public class flush {public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("b.txt", true);fw.append("鋤禾日當(dāng)午").append(",").append("汗滴禾下土");} }

結(jié)果還是空的,因?yàn)闆]有刷新緩沖區(qū):

如果加上flush:

FileWriter fw = new FileWriter("b.txt", true); fw.append("鋤禾日當(dāng)午").append(",").append("汗滴禾下土"); fw.flush();

結(jié)果為:

4、write:寫一個(gè)字符數(shù)組,字符數(shù)組的一部分,一個(gè)字符,一個(gè)字符串,字符串的一部分:

4.1.2 FileWriter類

使用默認(rèn)緩沖區(qū)大小將文本寫入字符文件。

構(gòu)造方法:

參數(shù):

1、File file / String fileName:要將內(nèi)容寫入的文件;

2、Charset charset:指定編碼集,常見的有"gbk"、“uft8”;

3、boolean append:是否是追加模式寫入;

方法沒有新的,都是用的或重寫的父類方法。

看個(gè)例子:

package com.kaikeba.coreclasslibrary.io;import java.io.FileWriter; import java.io.IOException; import java.io.Writer;public class writer {public static void main(String[] args) throws IOException {//Writer//FileWriterFileWriter fw = new FileWriter("b.txt");fw.write('a');fw.write("鋤禾日當(dāng)午");//注意append的用法,因?yàn)樗祷匚募旧?/span>fw.append(",").append("汗滴禾下土");fw.close();} }b.txt中的內(nèi)容為: a鋤禾日當(dāng)午,汗滴禾下土

4.2 字符輸入流Reader類

4.2.1 Reader類概述

用于讀取字符流的抽象類。常用的子類為InputStreamReader下的FileReader類。

方法:

常用的有:

1、close:關(guān)閉流

2、read:讀入一個(gè)字符,返回的就是它的int型編碼

3、將字符讀入數(shù)組(一部分)或指定緩沖區(qū)

4.2.2 FileReader類

使用默認(rèn)緩沖區(qū)大小從字符文件中讀取文本,使用指定的編碼集或默認(rèn)編碼集。

構(gòu)造方法:

參數(shù):

1、File file / String fileName:從哪個(gè)文件讀取;

2、Charset charset:指定編碼集。

方法也沒有新的。

看個(gè)例子:

package com.kaikeba.coreclasslibrary.io;import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException;public class reader {public static void main(String[] args) throws IOException {//ReaderFileReader fr = new FileReader("b.txt");/*while(true) {int c = fr.read();if(c == -1) {break;}System.out.print((char)c);}*/System.out.println("a:"+fr.read());System.out.println("鋤:"+fr.read());char[] chars = new char[100];int len = fr.read(chars);System.out.println(new String(chars, 0, len));fr.close();} }結(jié)果如下: a:97 鋤:38148 禾日當(dāng)午,汗滴禾下土

五、字節(jié)流轉(zhuǎn)換字符流

5.1 InputStreamReader類

InputStreamReader類是從字節(jié)流到字符流的橋接器,這也是比較常用的,比如從外界接收到的流一般都是字節(jié)流,如果要正確讀取文字的話,需要轉(zhuǎn)為字符流。每次調(diào)用read方法都可能導(dǎo)致從底層字節(jié)輸入流中讀取一個(gè)或者多個(gè)字節(jié)。

它是Reader類的一個(gè)子類,是FileReader的父類。

構(gòu)造方法:

主要的參數(shù)是要傳入一個(gè)字節(jié)輸入流InputStream。

方法:

主要是read方法,可以讀取一個(gè)字符或者將字符輸入數(shù)組的一部分。

看一個(gè)例子:

public class zhuanhuanliu {public static void main(String[] args) throws IOException {//字節(jié)流 ‘裝飾’為 字符流 :使用了裝飾者設(shè)計(jì)模式//自己新建一個(gè)字節(jié)輸入流,用于模仿外界接收到的FileInputStream fis = new FileInputStream("b.txt");//將字節(jié)輸入流,轉(zhuǎn)換為字符輸入流//參數(shù)1:要轉(zhuǎn)換的字節(jié)流//參數(shù)2:指定編碼名稱InputStreamReader isr = new InputStreamReader(fis,"utf8");while(true) {int c = isr.read();if(c == -1) {break;}System.out.print((char)c);}} }結(jié)果就是將b.txt中的內(nèi)容全部輸出

5.2 OutputStreamWriter類

OutputStreamWriter是從字符流到字節(jié)流的橋接器,使用指定的charset將寫入其中的字符編碼為字節(jié)。調(diào)用write方法都會(huì)導(dǎo)致在給定字符上調(diào)用編碼轉(zhuǎn)換器,生成的字節(jié)在寫入底層輸出流之前在緩沖區(qū)中累積。

它是Writer類的子類,是FileWriter類的父類。

構(gòu)造方法:

主要參數(shù)是要轉(zhuǎn)換的輸出字節(jié)流。

方法:

寫一個(gè)字符或字符串或字符數(shù)組的一部分。

看一個(gè)例子:

public class zhuanhuanliu2 {public static void main(String[] args) throws IOException {//轉(zhuǎn)換流//字符流 ‘裝飾’為 字節(jié)流 :使用了裝飾者設(shè)計(jì)模式FileOutputStream fos = new FileOutputStream("b.txt");OutputStreamWriter osw = new OutputStreamWriter(fos);osw.write("床前明月光");osw.close();} }即將“床前明月光”寫入b.txt。

六、打印流與緩存流

6.1 PrintStream類

PrintStream類向另一個(gè)輸出流添加功能,即能夠方便地打印各種數(shù)據(jù)值的表示。

構(gòu)造方法:

傳入的參數(shù)主要是要寫入的文件,可以是File型,String型或者字節(jié)輸出流。

方法:

1、追加:

2、關(guān)閉、刷新:

3、打印

4、打印并換行:

5、寫入:

看個(gè)例子:

public class print_bufferedreader {public static void main(String[] args) throws IOException {//(字符輸出)打印流,注意它會(huì)自動(dòng)刷新PrintStream ps = new PrintStream("b.txt");ps.println("鋤禾日當(dāng)午1");ps.println("鋤禾日當(dāng)午2");ps.println("鋤禾日當(dāng)午3");} }b.txt中的內(nèi)容就是: 鋤禾日當(dāng)午1 鋤禾日當(dāng)午2 鋤禾日當(dāng)午3

6.2 PrintWriter類

它和PrintStream類基本上差不多,主要的區(qū)別是寫入的時(shí)候不會(huì)自動(dòng)刷新。

public class print_bufferedreader {public static void main(String[] args) throws IOException {PrintWriter pw = new PrintWriter("b.txt");pw.println("鋤禾日當(dāng)午1");pw.println("鋤禾日當(dāng)午2");pw.println("鋤禾日當(dāng)午3");pw.flush();} }b.txt中的內(nèi)容就是: 鋤禾日當(dāng)午1 鋤禾日當(dāng)午2 鋤禾日當(dāng)午3

也可以用輸出流作為參數(shù):

public class print_bufferedreader {public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("b.txt");PrintWriter pw = new PrintWriter(fos);pw.println("勇敢牛牛");pw.close();} }b.txt中的內(nèi)容就是: 勇敢牛牛

6.3 BufferedReader類

從字符輸入流中讀取文本,緩沖字符,以便有效地讀取字符,數(shù)組和行??梢灾付ň彌_區(qū)大小,或者可以使用默認(rèn)大小。

構(gòu)造方法:

方法:

它比較獨(dú)特的一個(gè)方法是readLine方法:讀取一行文字,看一個(gè)例子:

public class print_bufferedreader {public static void main(String[] args) throws IOException {//緩存讀取流,將字符輸入流 轉(zhuǎn)換為帶有緩存 可以一次讀取一行的緩存字符讀取流FileReader fw = new FileReader("b.txt");BufferedReader br = new BufferedReader(fw);String text = br.readLine();System.out.println(text);} }結(jié)果解釋讀取b.txt中的一行文字。

七、收集異常日志

在程序運(yùn)行過程中,不可能一直看著屏幕上的輸出,所以當(dāng)出現(xiàn)異常的時(shí)候,利用IO我們可以將這些異常寫到指定的文件中,后續(xù)有時(shí)間打開這個(gè)記錄異常的文件查看即可。

看一個(gè)例子:

public class printstacktrace {public static void main(String[] args) throws FileNotFoundException {try{//將可能出現(xiàn)異常的內(nèi)容用try捕捉String s = null;s.toString();}catch (Exception e) {//新建打印流,指定輸出的文件PrintWriter pw = new PrintWriter("b.txt");//把時(shí)間也記錄下來SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");pw.println(sdf.format(new Date()));//將異常輸出到打印流中e.printStackTrace(pw);//關(guān)閉打印流pw.close();}} }b.txt中的內(nèi)容就是異常: 2021-09-13 19:57 java.lang.NullPointerExceptionat com.kaikeba.coreclasslibrary.io.printstacktrace.main(printstacktrace.java:12)

總結(jié)

以上是生活随笔為你收集整理的JavaSE——IO(上)(File、字节流、字符流、转换流、打印流、缓存流)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。