Java基礎(chǔ)文件操作(IO流)

      網(wǎng)友投稿 833 2022-05-28

      特意寫一章關(guān)于IO流的知識(shí),不為別的,是因?yàn)镮O流實(shí)在太重要了

      文件

      File?就是文件對(duì)象,我們電腦上的文件和文件夾都可以用這個(gè)File實(shí)例化

      public?class?Test{ ????public?static?void?main(String[]?args){ ????????//?獲取絕對(duì)路徑D盤的hello文件夾 ????????File?f1?=?new?File("D:/hello"); ????????//?獲取相對(duì)路徑的hello.txt文件 ????????File?f2?=?new?File("hello.txt"); ????????//?獲取D盤的hello文件夾下hello.txt文件的實(shí)例 ????????File?f3?=?new?File(f1,"hello.txt"); ???????? ????????//?輸出三個(gè)文件或者文件夾的絕對(duì)路徑 ????????System.out.println(f1.getAbsolutePath()); ????????System.out.println(f2.getAbsolutePath()); ????????System.out.println(f3.getAbsolutePath()); ????}}123456789101112131415

      上面代碼注釋講的已經(jīng)非常的詳細(xì)了,用三種方式創(chuàng)建一個(gè)文件對(duì)象,怎么獲取文件的絕對(duì)路徑

      假設(shè)我們已經(jīng)實(shí)例化了一個(gè)File對(duì)象f

      判斷是否存在?f.exists()

      判斷是否是文件夾?f.isDirectory()

      判斷是否是文件?f.isFile()

      獲取文件的長度?f.length()

      文件最后修改的時(shí)間?f.lastModified()

      設(shè)置文件最后修改時(shí)間?f.setLastModified(0)?這里的0代表的是時(shí)間戳 也就是1970.1.1 08:00:00

      文件重命名?f.renameTo(“newName”)

      以字符串?dāng)?shù)組的形式,返回當(dāng)前文件夾下面的所有文件?f.list()

      以文件數(shù)組的形式,返回當(dāng)前文件夾下面的所有文件?f.listFiles()

      以字符串形式返回所在文件夾?f.getParent()

      以字符串形式返回獲取所在文件夾?f.getParentFile()

      創(chuàng)建一個(gè)文件夾?f.mkdir()?如果說f所在的父文件夾不存在就會(huì)拋出異常

      創(chuàng)建一個(gè)文件夾?f.mkdirs()?如果說f所在的父文件夾不存在就會(huì)自動(dòng)給你創(chuàng)建一個(gè)父文件夾

      刪除文件?f.delete()

      JVM結(jié)束的時(shí)候刪除文件?f.deleteOnExit()

      public?class?Test{ ????public?static?void?main(StringP[]?args){ ????????File?f?=?new?File("C:/WINDOWS"); ????????File[]?files; ????????int?k=0; ????????long?max?=?0; ????????if(f.exists){ ????????????//?把文件夾下面的所有文件都取出來 ????????????files?=?f.listFiles(); ????????????//?遍歷所有的文件取出體積最大的文件 ????????????for(int?i=0;imax){ ????????????????????//如果比最大的文件還大就把他的下標(biāo)記下來 ????????????????????k?=?i; ????????????????????max?=?files[i].length(); ????????????????} ????????????} ????????}else{ ????????????System.out.println("文件夾不存在"); ????????} ???????? ????????//?輸出找到的最大的文件路徑和它體積 ????????System.out.println("最大文件路徑:?"+files[k]); ????????System.out.println("最大文件體積:?"+files[k].length()+"?字節(jié)"); ????}}1234567891011121314151617181920212223242526

      編碼

      編碼是信息從一種形式或格式轉(zhuǎn)換為另一種形式的過程

      常見的編碼方式有如下幾種:

      ISO-8859-1 ASCII?數(shù)字和西歐字母

      GBK GB2312 BIG5?中文

      UNICODE?(統(tǒng)一碼,萬國碼)

      看樣子,我們的中文就是屬于這個(gè)GBK這種編碼了,也就是說中文只能用GBK編碼來存儲(chǔ)嘛?

      這個(gè)肯定是錯(cuò)的,UNICODE稱為萬國碼,也就是全世界任何國家的字符都是可以儲(chǔ)存的,只不過,他占用的空間是最大的,比入英文字母只需要1字節(jié)的空間,漢字需要3字節(jié)的空間,但是Unicode它不管你是英文字母還是漢字,都統(tǒng)一給你4個(gè)字節(jié),這樣的話是比較浪費(fèi)空間的,所以就誕生了UTF-8這種基于Unicode減肥版本的編碼方式。

      UTF-8它可以對(duì)英文或者數(shù)字使用一個(gè)字節(jié),對(duì)漢字使用三個(gè)字節(jié),這樣的話就避免了空間的浪費(fèi)。

      Java源代碼中的漢字在執(zhí)行之后,都會(huì)變成JVM中的字符,而這些中文字符采用的編碼方式,都是Unicode

      什么流?流就是一系列的數(shù)據(jù)。

      當(dāng)不同的介質(zhì)之間有數(shù)據(jù)交互的時(shí)候,Java就是使用流來實(shí)現(xiàn)

      比如讀取文件的數(shù)據(jù)到程序中,站在程序的角度來看,就叫做輸入流。

      如何創(chuàng)建文件輸入流,看以下代碼:

      public?class?Test{ ????public?static?void?main(String[]?args){ ????????try{ ????????????File?f?=?new?File("D:/hello.txt"); ????????????//?通過這個(gè)文件輸入流可以將硬盤上文件中的數(shù)據(jù)讀取到j(luò)ava程序內(nèi)存中來 ????????????FileInputStream?fis?=?new?FileInputStream(f); ????????}catch(IOException?e){ ????????????e.printStackTrace(); ????????} ????}}1234567891011

      InputStream是字節(jié)輸入流,同時(shí)也是抽象類,只提供方法聲明,不提供方法的具體實(shí)現(xiàn)。

      FileInputStream是InputStream的子類,我們下面就用FileInputStream來實(shí)現(xiàn)讀取文件的內(nèi)容

      public?class?Test{ ????public?static?void?main(String[]?args){ ????????try{ ????????????//?準(zhǔn)備一個(gè)文本文件,里面內(nèi)容是AB ????????????File?f?=?new?File("D:/test.txt"); ????????????//?創(chuàng)建文件輸入流 ????????????FileInputStream?fis?=?new?FileInputStream(f); ????????????//?創(chuàng)建一個(gè)字節(jié)數(shù)組,它的長度就是文件的長度 ????????????byte[]?all?=?new?byte[(int)f.length()]; ????????????//?以字節(jié)流的形式讀取文件中的所有內(nèi)容到字節(jié)數(shù)組 ????????????fis.read(all); ????????????for(byte?b?:?all){ ????????????????System.out.println(b); ???????????} ????????????fis.close(); ???????????? ????????}catch(IOException?e){ ????????????e.printStackTrace(); ????????} ????}}123456789101112131415161718192021

      結(jié)果是65和66 也就是A和B對(duì)應(yīng)的ASCII碼

      OutputStream 是字節(jié)輸出流,更InputStream也是一樣的,抽象類。

      所以我們用FileOutputStream為例往文件中寫入數(shù)據(jù)

      public?class?Test{ ????public?static?void?main(String[]?args){ ????????try{ ????????????//?準(zhǔn)備一個(gè)文本文件,里面內(nèi)容是空的 ????????????File?f?=?new?File("D:/test.txt"); ????????????//?創(chuàng)建文件輸出流 ????????????FileOutputStream?fis?=?new?FileOutputStream(f); ????????????//?創(chuàng)建一個(gè)字節(jié)數(shù)組,里面寫上A和B的ASCII碼 ????????????byte[]?data?=?{65,66}; ????????????//?以字節(jié)流的形式將data里的數(shù)據(jù)寫入到輸出流 ????????????fis.write(all); ????????????fis.close();? ????????}catch(IOException?e){ ????????????e.printStackTrace(); ????????} ????}}1234567891011121314151617

      我們打開對(duì)應(yīng)的文件,發(fā)現(xiàn)數(shù)據(jù)就已經(jīng)寫在里面了,但是輸出流跟輸入流有一個(gè)區(qū)別,就是輸出流的時(shí)候不一定要求文件存在,當(dāng)文件不存在的時(shí)候,會(huì)自動(dòng)給我們創(chuàng)建一個(gè)新的文件,而輸入流則會(huì)拋出異常

      字符流:就是在字節(jié)流的基礎(chǔ)上,加上編碼,形成的數(shù)據(jù)流

      字符流分為字符輸入流Reader 和 字符輸出流 Writer

      他們常用的子類就是FileReader 和 FileWriter

      在之前我們使用了字節(jié)輸入流讀取文件中的內(nèi)容,讀取的AB打印出來是65和66

      現(xiàn)在我們來看一下使用字符輸入流讀取文件是什么樣的結(jié)果

      public?class?Test?{ ? ????public?static?void?main(String[]?args)?{ ????????//?準(zhǔn)備文件hello.txt其中的內(nèi)容是AB ????????File?f?=?new?File("d:/hello.txt"); ????????//?創(chuàng)建基于文件的Reader ????????try?(FileReader?fr?=?new?FileReader(f))?{ ????????????//?創(chuàng)建字符數(shù)組,其長度就是文件的長度 ????????????char[]?all?=?new?char[(int)?f.length()]; ????????????//?以字符流的形式讀取文件所有內(nèi)容 ????????????fr.read(all); ????????????for?(char?b?:?all)?{ ????????????????//?打印出來是A?B ????????????????System.out.println(b); ????????????} ????????}?catch?(IOException?e)?{ ????????????//?TODO?Auto-generated?catch?block ????????????e.printStackTrace(); ????????} ? ????}}12345678910111213141516171819202122

      字符輸入流可以直接讀取文件中的字符

      我們可以直接將一串字符存儲(chǔ)到文件中,代碼如下:

      public?class?Test{ ????public?static?void?main(String[]?args){ ????????//?創(chuàng)建文件對(duì)象,文件內(nèi)容是空的 ????????File?f?=?new?File("D:/hello.txt"); ????????//?要寫入的字符串 ????????String?str?=?"hello"; ?????? char[]?cs?=?str.toCharArray(); ????????try(FileWrter?fw?=?new?FileWriter(f)){ ????????????fw.write(cs) ????????}catch(IOException?e){ ????????????e.printStackTrace(); ????????} ????}}1234567891011121314

      文件中的內(nèi)容就會(huì)變稱hello

      上面我們學(xué)習(xí)了字節(jié)流和字符流,那么我們分別用兩種流來從文件中讀取漢字內(nèi)容。

      首先你得了解文本是以哪種編碼方式進(jìn)行保存的

      Java基礎(chǔ)之文件操作(IO流)

      使用字節(jié)流讀取文本后,再使用對(duì)應(yīng)的編碼方式去識(shí)別這些文字

      public?class?Test{ ????File?f?=?new?File("D:/hello.txt"); ????try(FileInputStream?fis?=?new?FileInputStream(f)){ ????????byte[]?all?=?new?byte[(int)?f.length()]; ????????fis.read(all); ????????//將讀到的字節(jié)進(jìn)行編碼輸出 ????????String?str?=?new?String(all,"GBK"); ????????System.out.println(str); ????}catch(IOException?e){ ????????e.printStackTrace(); ????}}123456789101112

      FileReader得到的字符,肯定是已經(jīng)把字節(jié)根據(jù)某種編碼方式識(shí)別成的字符。

      FIleReader的編碼方式可以用Charset.defaultCharset()獲取,如果是中文的操作系統(tǒng)那么就是GBK

      假設(shè)現(xiàn)在我們的文件是用UTF-8編碼方式保存的,那么我們?cè)撊绾问褂米址髯x取文字呢?

      答案就是使用InputStreamReader,這個(gè)是字節(jié)流到字符流的橋接器,它可以按照指定的字符集讀取字節(jié)并將它們轉(zhuǎn)換為字符。

      public?class?TestStream?{ ????public?static?void?main(String[]?args)?throws?UnsupportedEncodingException,?FileNotFoundException?{ ????????File?f?=?new?File("D:/hello.txt"); ????????System.out.println("默認(rèn)編碼方式:"+Charset.defaultCharset()); ????????//FileReader得到的是字符,所以一定是已經(jīng)把字節(jié)根據(jù)某種編碼識(shí)別成了字符了 ????????//而FileReader使用的編碼方式是Charset.defaultCharset()的返回值,如果是中文的操作系統(tǒng),就是GBK ????????try?(FileReader?fr?=?new?FileReader(f))?{ ????????????char[]?cs?=?new?char[(int)?f.length()]; ????????????fr.read(cs); ????????????System.out.printf("FileReader會(huì)使用默認(rèn)的編碼方式%s,識(shí)別出來的字符是:%n",Charset.defaultCharset()); ????????????System.out.println(new?String(cs)); ????????}?catch?(IOException?e)?{ ????????????//?TODO?Auto-generated?catch?block ????????????e.printStackTrace(); ????????} ????????//FileReader是不能手動(dòng)設(shè)置編碼方式的,為了使用其他的編碼方式,只能使用InputStreamReader來代替 ????????//并且使用new?InputStreamReader(new?FileInputStream(f),Charset.forName("UTF-8"));?這樣的形式 ????????try?(InputStreamReader?isr?=?new?InputStreamReader(new?FileInputStream(f),Charset.forName("UTF-8")))?{ ????????????char[]?cs?=?new?char[(int)?f.length()]; ????????????isr.read(cs); ????????????System.out.printf("InputStreamReader?指定編碼方式UTF-8,識(shí)別出來的字符是:%n"); ????????????System.out.println(new?String(cs)); ????????}?catch?(IOException?e)?{ ????????????//?TODO?Auto-generated?catch?block ????????????e.printStackTrace(); ????????} ????????? ????}}1234567891011121314151617181920212223242526272829

      為什么中字的前面有一個(gè)?,如果你是用記事本另存為UTF-8的字符集編碼的話,那么在第一個(gè)字節(jié)有一個(gè)標(biāo)識(shí),叫做BOM,用來標(biāo)識(shí)這個(gè)文件是使用UTF-8編碼的

      以介質(zhì)是硬盤為例,字節(jié)流和字符流的弊端:

      在每一次讀寫的時(shí)候,都會(huì)訪問硬盤。 如果讀寫的頻率比較高的時(shí)候,其性能表現(xiàn)不佳。

      為了解決以上弊端,采用緩存流。

      緩存流在讀取的時(shí)候,會(huì)一次性讀較多的數(shù)據(jù)到緩存中,以后每一次的讀取,都是在緩存中訪問,直到緩存中的數(shù)據(jù)讀取完畢,再到硬盤中讀取。

      就好比吃飯,不用緩存就是每吃一口都到鍋里去鏟。用緩存就是先把飯盛到碗里,碗里的吃完了,再到鍋里去鏟

      緩存流在寫入數(shù)據(jù)的時(shí)候,會(huì)先把數(shù)據(jù)寫入到緩存區(qū),直到緩存區(qū)達(dá)到一定的量,才把這些數(shù)據(jù),一起寫入到硬盤中去。按照這種操作模式,就不會(huì)像字節(jié)流,字符流那樣每寫一個(gè)字節(jié)都訪問硬盤,從而減少了IO操作

      BufferedReader可以一次性讀取一行數(shù)據(jù)

      public?class?Test{ ????public?static?void?main(String[]?args){ ????????/** ????????準(zhǔn)備一個(gè)文件,里面的內(nèi)容是 ????????hello ????????world ????????你好 ????????*/ ????????File?f?=?new?File("d:/hello.txt"); ????????//?緩存字符輸入流必須在一個(gè)存在的流的基礎(chǔ)上創(chuàng)建 ????????try( ????????FileReader?fr?=?new?FileReader(f); ????????BufferedReader?br?=?new?BufferedReader(fr); ????????????){ ????????????while(true){ ????????????????//?一次讀取一行 ????????????????String?line?=?br.readLine(); ????????????????if(line?==?null){ ????????????????????break; ????????????????} ????????????????System.out.println(line); ????????????}catch(IOException?e){ ????????????????e.printStackTrace(); ????????????} ????????} ????}}123456789101112131415161718192021222324252627

      PrintWrite,可以一次寫出一行數(shù)據(jù)

      public?class?TestStream?{ ??? ????public?static?void?main(String[]?args)?{ ????????//?向文件lol2.txt中寫入三行語句 ????????File?f?=?new?File("d:/hello.txt"); ?????????? ????????try?(?????????? ????????????????PrintWriter?pw?=?new?PrintWriter(f);?????????????? ????????)?{ ????????????pw.println("hello"); ????????????pw.println("world"); ????????????pw.println("你好"); ????????}?catch?(IOException?e)?{ ????????????//?TODO?Auto-generated?catch?block ????????????e.printStackTrace(); ????????} ??? ????}}12345678910111213141516171819

      這里需要注意的是,緩存字符輸入流的構(gòu)造方法的參數(shù)是一個(gè)Reader,也就是一個(gè)字符流,而PrintWriter的構(gòu)造參數(shù)可以是文件對(duì)象也可以是字節(jié)流或者字符流對(duì)象!

      分別是BufferedInputStream 和 BufferedOutputStream

      下面代碼演示的是通過緩存字節(jié)輸入流和輸出流實(shí)現(xiàn)文件的復(fù)制

      public?class?Test{ ????public?static?void?main(String[]?args){ ????????File?file?=?new?File("E:/我的文檔/臨時(shí)文件/視屏文件.ts"); ????????File?file1?=?new?File("E:/我的文檔/臨時(shí)文件/視屏文件(副本).ts"); ????????try?( ????????????????FileInputStream?fis?=?new?FileInputStream(f); ????????????????FileOutputStream?fos?=?new?FileOutputStream(f1); ????????????????BufferedInputStream?bis?=?new?BufferedInputStream(fis); ????????????????BufferedOutputStream?bos?=?new?BufferedOutputStream(fos); ????????){ ????????????byte[]?bytes?=?new?byte[1024]; ????????????int?len; ????????????while(true){ ????????????????len?=?bis.read(bytes); ????????????????if(len?==?-1){ ????????????????????break; ????????????????} ????????????????bos.write(bytes,0,len); ????????????} ????????}catch?(IOException?e){ ????????????e.printStackTrace(); ????????} ????} ????}}

      Java

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:系統(tǒng)分析之100億級(jí)日志系統(tǒng)是怎么設(shè)計(jì)出來的?
      下一篇:圖文詳解 HDFS 組成框架
      相關(guān)文章
      中文字幕亚洲电影| 亚洲a在线视频视频| 中文字幕亚洲综合久久| 亚洲人成人网站色www| 亚洲日韩在线中文字幕综合 | 亚洲欧美一区二区三区日产| 亚洲一区二区三区不卡在线播放| 亚洲视频网站在线观看| 亚洲综合自拍成人| 久久亚洲熟女cc98cm| 婷婷亚洲久悠悠色悠在线播放| 亚洲产国偷V产偷V自拍色戒 | 亚洲精品乱码久久久久久| 国产亚洲免费的视频看| 亚洲精品色午夜无码专区日韩| 亚洲中文字幕无码不卡电影| 亚洲人成色7777在线观看| 亚洲精品tv久久久久久久久| 亚洲AV无码国产在丝袜线观看| 久久精品国产96精品亚洲 | 亚洲黄网在线观看| 亚洲综合激情另类小说区| 亚洲精品美女在线观看| 亚洲一区二区三区在线观看蜜桃| 67194在线午夜亚洲| 亚洲日韩国产一区二区三区在线| 亚洲狠狠色丁香婷婷综合| 国产成人+综合亚洲+天堂| 亚洲人成电影网站国产精品| 国产亚洲大尺度无码无码专线 | 久久精品国产亚洲麻豆| 亚洲国产精品国自产拍电影| 亚洲女人影院想要爱| 亚洲高清有码中文字| 性色av极品无码专区亚洲| 亚洲色偷拍区另类无码专区| 在线观看亚洲精品国产| 亚洲AV成人一区二区三区AV| 亚洲国产韩国一区二区| 亚洲中文字幕无码中文字| 男人的天堂亚洲一区二区三区 |