Java文件IO常用歸納

我們常說的標準IO操作,包含了本篇所述的文件IO苟蹈。我們知道糊渊,IO無非是輸入輸出,數據在動的時候以流形式存在(Byte or Bit 為單位)慧脱,而在靜的時候則以文件形式存在(因為我們知道文件就是若干Byte等單位的數據或數據集合)渺绒。

前言:關于文件的編碼


  1. 在windows 下,eclipse等IDE的默認項目編碼是GBKGBK編碼:中文占用2byte宗兼,英文占用1byte躏鱼。
  2. utf-8編碼中:中文占用3byte,英文占用1byte殷绍。
  3. 如何把單個字節(jié)轉換為int以16進制的方式顯示:
String ch = "A";
byte[] bytes = ch.getBytes();
System.out.println(Integer.toHexString(bytes[0] & 0xff));///為了將變成int類型后(8bit->32bit)的值染苛,除去前30位的值,只留下最低2位主到。
  1. Java是雙字節(jié)編碼(utf-16be)茶行,utf-16be編碼:中文和英文都占用2byte。
  2. Java中字符串與字節(jié)序列之間的轉換示例:
String str = "你好1234";
byte[] bytes = str.getBytes("utf-16be");
String str2 = new String(bytes, "utf-16be");
  1. 文本文件(.txt)就是字節(jié)序列(可以是任意編碼的字節(jié)序列)
  2. 中文機器上(比如我們的PC)直接創(chuàng)建文本文件镰烧,那么該文件只認識ansi編碼
  3. 創(chuàng)建的Java項目設定是utf-8編碼,那么楞陷, 它創(chuàng)建的文本文件編碼格式就是utf-8編碼怔鳖。將此文本文件拷貝到其他不是utf-8編碼的項目目錄下,就會亂碼固蛾。但是將此文本文件拷貝到我們PC的任何其他目錄下结执,都不會有亂碼。(注意是拷貝艾凯,不是新建献幔,這是由于:文本文件本身就是識別任意編碼格式的字節(jié)序列)

Java IO示例與注意點


(一)File類

  1. 創(chuàng)建/獲取文件對象,使用File.separator分隔符:
File file = new File("E:\\test");///一般windows下用(雙斜杠)
//File file0 = new File("e:\\", "diary.txt");
File file2 = new File("E:/test");///一般linux和macos下用(反斜杠)
File file3 = new File("E:" + File.separator +"test");///系統(tǒng)間通用
  1. 創(chuàng)建的文件對象是一個多級目錄時趾诗,需要File.mkdirs()而不是File.mkdir()
if(!file.exists())
    file.mkdirs();
  1. 打印File.toString()蜡感,默認打印文件的目錄:
System.out.println(file);/// output: e://test

(二)文件讀寫IO

  1. 關于RandomAccessFile:RandomAccessFile類支持隨機訪問文件并可以訪問文件的任意位置:read()write()就是這個類的其他方法的基礎原理。
RandomAccessFile raf = new RandomAccessFile(file, "rw");//兩個模式:rw表示讀寫恃泪,r表示只讀郑兴。
raf.write(int);//只寫一個字節(jié)(后8位),同時指針后移一個位置贝乎,準備再次寫入情连。
int b = raf.read();//讀一個字節(jié)
int max = 0x7ffffff;
raf.write(max>>>24);//最高8位
raf.write(max>>>16);//8位
raf.write(max>>>8);//8位
raf.write(max);///最低8位
  1. IO流基礎
  • 分為:字節(jié)流、字符流
  • EOF = End:-1表示讀到結尾
  • 字節(jié)流:InputStream览效、OutputStream(抽象類)【具體方法可以查看它的API文檔】
    • 輸入流最重要方法:
      int b = in.read();///讀取一個字節(jié)無符號填充到int低8位却舀。-1表示EOF
      in.read(byte[] buf);///讀取內容到buf字節(jié)數組中
      in.read(byte[] buf , int start, int size);//讀取內容的一小段,到buf
      
    • 輸出流最重要方法:
      out.write(int b);///寫出一個字節(jié)到流锤灿,b的低8位挽拔。
      out.write(byte[] buf);//將buf字節(jié)數組寫入到流
      out.write(byte[] buf, int start, int size);///將將buf[start]開始的size長度內容寫入。
      
    • 各種字節(jié)流實現類:
      • 【基本文件操作】FileInputStream/FileOutputStream:具體實現了在文件上存取byte數據的方法但校。
      • 【更多封裝方法】DataInputStream/DataOutputStream:對“流”進行了擴展篱昔,可以更方面地讀取int、long、字符等類型數據【相當于比FileInputStream等多了些封裝方法(裝飾模式)】
      DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
      dos.writeUTF("中國");//采用utf-8編碼寫出
      dos.writeChars("中國");//采用utf-16be編碼寫出
      
      • 【更高效率】BufferedInputStream/BufferedOutputStream:為流IO提供了帶緩沖區(qū)的操作州刽,一般打開文件進行IO操作時空执,都會用到,這種流模式提高IO性能穗椅。
  • 字符流
    • 注意編碼問題
    • 文本與文本文件的區(qū)別:
      • Java的文本(char)是16位無符號整數(unsigned 16bit int),是字符的unicode編碼(雙字節(jié)編碼)辨绊。
      • 文本文件是文本(char)序列按照某種方案(如:utf-8、utf-16be匹表、gbk等)序列化為byte的存儲結果门坷。
    • 【基本實現】InputStreamReader/OutputStreamWriter:完成byte-->char的按編碼解析/char-->byte的按編碼處理
    InputStreamReader isr = new InputStreamReader(new FileInputStream(file));///默認使用項目的編碼格式(非utf-16be)
    char[] chs = new char[1024];
    int len;
    while((len=isr.read(chs,0,chs.length))!=-1){
      String s = new String(chs,0,len);
      System.out.println(s);
    }
    
    • FileReader/FileWriter:可直接對文本文件進行字符流讀寫。在copy文件時袍镀,可覆蓋或追加文件內容默蚌。不用byte轉char,但是編碼問題不能解決苇羡。
    • BufferedReader/BufferedWriter:帶緩沖绸吸,(String line = br.readLine())!=null方法可以一次讀一行,高效率设江,但不能識別換行锦茁。
    BufferedReader br = new BufferedReader(new InputStreamReader(
                                      newFileInputStream(file)));//讀
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                                      newFileOutputStream(newFilePath)));//寫
    String line;
    while((line = br.readLine())!=null){
      ///輸出并寫入新文件
      bw.write(line);
      bw.newLine();///單獨寫出換行操作!2娲妗码俩!
      bw.flush;
    }
    br.close();
    bw.close();
    
    • PrintWriter:簡單化構造一個寫入流,換行操作很方面:println(str);

(三)對象讀寫 與 序列化

  1. 序列化:Object轉byte序列的過程歼捏。
  2. 序列化流:ObjectOutputStream/ObjectInputStream稿存,對于方法:writeObject()、readObject()
  3. JVM在對象內部調用的默認序列化方法:
///成員方法writeObject()
public void writeObject(ObjectOutputStream s) throws IOException{
  s.defaultWriteObject();
}
  1. 如果想要自己做某個元素的序列化操作:
public void writeObject(ObjectOutputStream s) throws IOException{
  s.defaultWriteObject();
  s.writeInt(age);///如這個age變量瞳秽,就被我們自行序列化寫入了
}
  1. Serializable接口是一個標準挠铲,是序列化的前提。
  2. transient關鍵字:被標注的成員不會被jvm進行默認序列化寂诱》髌唬【有時可以提高性能】
  3. ArrayList內部維護著Object[]類型的數組對象,這個對象是被transient修飾的痰洒,但是ArrayList并不是不想進行序列化操作瓢棒,而是想自己去實現序列化的方式而不去給JVM默認進行序列化,這樣一來即可提高效率丘喻。
  4. 序列化時:一個類實現了Serializable接口脯宿,其子類都能夠被需序列化。
  5. 反序列化時:對子類對象進行反序列化泉粉,如果其父類沒有實現Serializable接口连霉,則其父類的構造方法會被調用榴芳。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市跺撼,隨后出現的幾起案子窟感,更是在濱河造成了極大的恐慌,老刑警劉巖歉井,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柿祈,死亡現場離奇詭異,居然都是意外死亡哩至,警方通過查閱死者的電腦和手機躏嚎,發(fā)現死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來菩貌,“玉大人卢佣,你說我怎么就攤上這事〖祝” “怎么了虚茶?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長尾膊。 經常有香客問我媳危,道長荞彼,這世上最難降的妖魔是什么冈敛? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮鸣皂,結果婚禮上抓谴,老公的妹妹穿的比我還像新娘。我一直安慰自己寞缝,他們只是感情好癌压,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著荆陆,像睡著了一般滩届。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上被啼,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天帜消,我揣著相機與錄音,去河邊找鬼浓体。 笑死泡挺,一個胖子當著我的面吹牛,可吹牛的內容都是我干的命浴。 我是一名探鬼主播娄猫,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼贱除,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了媳溺?” 一聲冷哼從身側響起月幌,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎褂删,沒想到半個月后飞醉,有當地人在樹林里發(fā)現了一具尸體玄括,經...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡摹芙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年判没,在試婚紗的時候發(fā)現自己被綠了宝泵。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片背苦。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡笆怠,死狀恐怖极祸,靈堂內的尸體忽然破棺而出祠汇,到底是詐尸還是另有隱情盖袭,我是刑警寧澤失暂,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站鳄虱,受9級特大地震影響弟塞,放射性物質發(fā)生泄漏。R本人自食惡果不足惜拙已,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一决记、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧倍踪,春花似錦系宫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至缤至,卻和暖如春潮罪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背领斥。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工嫉到, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人戒突。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓屯碴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親膊存。 傳聞我的和親對象是個殘疾皇子导而,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內容