Java IO詳解

IO 是什么?其實就是Java中的一種輸入和輸出功能,也可以理解為對文件的寫入和讀出的操作,只不過Java中對這種操作叫做對流的操作。而流不只是對文件進(jìn)行讀寫,還可以對內(nèi)存,網(wǎng)絡(luò),程度操作。

一、字節(jié)與字符

在Java中有輸入、輸出兩種IO流,每種輸入、輸出流又分為字節(jié)流和字符流兩大類。

  • 關(guān)于字節(jié),每個字節(jié)(byte)有8bit組成。
  • 關(guān)于字符,我們可能知道代表一個漢字或者英文字母。

字節(jié)與字符之間的關(guān)系
Java采用unicode編碼,通講,2個字節(jié)來表示一個字符。
在0~127整數(shù)之間的字符映射,unicode向下兼容ASCII,也就是1個字節(jié)表示一個字符。
一個中文或英文字符的unicode編碼都占2個字節(jié)。

編碼方式 英文字符 中文字符
GB 2312、GBK 1 2
UTF-8 1 3-4
UTF-16 2 3-4
UTF-32 4 4

二、File

文件和文件夾的操作都可以用File來完成。

文件的獲取
File.png
//構(gòu)造函數(shù)File(String pathname)
File f1 =new File("c:\\abc\\1.txt");
//File(String parent,String child)
File f2 =new File("c:\\abc","2.txt");
//File(File parent,String child)
File f3 =new File("c:"+File.separator+"abc");//separator 跨平臺分隔符
File f4 =new File(f3,"3.txt");
System.out.println(f1);//c:\abc\1.txt
文件的創(chuàng)建以及刪除
//如果文件存在返回false,否則返回true并且創(chuàng)建文件 
boolean createNewFile();
//創(chuàng)建一個File對象所對應(yīng)的目錄,成功返回true,否則false。且File對象必須為路徑而不是文件。只會創(chuàng)建最后一級目錄,如果上級目錄不存在就拋異常。
boolean mkdir();
//創(chuàng)建一個File對象所對應(yīng)的目錄,成功返回true,否則false。且File對象必須為路徑而不是文件。創(chuàng)建多級目錄,創(chuàng)建路徑中所有不存在的目錄
boolean mkdirs()    ;
//如果文件存在返回true并且刪除文件,否則返回false
boolean delete();
//在虛擬機(jī)終止時,刪除File對象所表示的文件或目錄。
void deleteOnExit();
判斷方法
boolean canExecute()    ;//判斷文件是否可執(zhí)行
boolean canRead();//判斷文件是否可讀
boolean canWrite();//判斷文件是否可寫
boolean exists();//判斷文件是否存在
boolean isDirectory();//判斷是否是目錄
boolean isFile();//判斷是否是文件
boolean isHidden();//判斷是否是隱藏文件或隱藏目錄
boolean isAbsolute();//判斷是否是絕對路徑 文件不存在也能判斷

作者:Ruheng
鏈接:http://www.lxweimin.com/p/c58ed5ec7e4a
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
獲取參數(shù)方法
String getName();//返回文件或者是目錄的名稱
String getPath();//返回路徑
String getAbsolutePath();//返回絕對路徑
String getParent();//返回父目錄,如果沒有父目錄則返回null
long lastModified();//返回最后一次修改的時間
long length();//返回文件的長度
File[] listRoots();// 列出所有的根目錄(Window中就是所有系統(tǒng)的盤符)
String[] list() ;//返回一個字符串?dāng)?shù)組,給定路徑下的文件或目錄名稱字符串
String[] list(FilenameFilter filter);//返回滿足過濾器要求的一個字符串?dāng)?shù)組
File[]  listFiles();//返回一個文件對象數(shù)組,給定路徑下文件或目錄
File[] listFiles(FilenameFilter filter);//返回滿足過濾器要求的一個文件對象數(shù)組

其中FilenameFileter 是一個文件過濾器。找到所有png圖片。

        file.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(".png");
            }
        });

三、IO流

Java的IO流是實現(xiàn)輸入/輸出的基礎(chǔ),它可以方便地實現(xiàn)數(shù)據(jù)的輸入/輸出操作,在Java中把不同的輸入/輸出源抽象表述為"流"。
流是一組有順序的字節(jié)集合,是對數(shù)據(jù)傳輸?shù)目偡Q或抽象。
流有輸入和輸出,輸入時是流從數(shù)據(jù)源流向程序。輸出時是流從程序傳向數(shù)據(jù)源,而數(shù)據(jù)源可以是內(nèi)存,文件,網(wǎng)絡(luò)或程序等。

四、分類

  • 按照流向不同,分為 輸入流、輸出流
  • 按照流對象不同,分為 字節(jié)流、字符流

字節(jié)流可以處理任意類型的數(shù)據(jù),而字符只能處理字符類型的數(shù)據(jù)

  • 按照處理過程不同,分為 節(jié)點流、處理流(一種典型的裝飾器模式)

五、4中基本方式的講解 和 實例

4種基本方式
  • inputStream
  • outputStream
  • Reader
  • Write
    四大抽象基類,其中inputStream,outputStream是字節(jié)流的基類,Reader,Write是字符流的基類。不能創(chuàng)建實例,但是為所有實現(xiàn)類提供了基礎(chǔ)的模板。
inputStream
inputStream.png
outputStream
outputStream.png
Reader
Reader.png
Write
Write.png

總結(jié):
從上面的方法中我可以看出。inputStreamreaderoutputStreamwrite的函數(shù)都很相似,并且每次進(jìn)行了IO操作,要記得close,因為IO資源并不屬于內(nèi)存資源,并不會被GC回收。所以需要顯示的 手動的回收資源。對于輸出操作,close還會自動flush

六、RandomAccessFile的使用與簡介

RandomAccessFile簡介

我們在對文件的操作過程中,除了使用字節(jié)流和字符流的方式之外,我們還可以使用RandomAcessFile這個工具類來實現(xiàn)。

RandomAccessFile可以實現(xiàn)對文件的,但是他并不是繼承于以上4中基本虛擬類。

而且在對文件的操作中,RandomAccessFile有一個巨大的優(yōu)勢,他可以支持文件的隨機(jī)訪問,程序快可以直接跳轉(zhuǎn)到文件的任意地方來讀寫數(shù)據(jù)。所以如果需要訪問文件的部分內(nèi)容,而不是把文件從頭讀到尾,使用RandomAccessFile將是更好的選擇。

RandomAccessFile的方法雖然多,但它有一個最大的局限,就是只能讀寫文件,不能讀寫其他IO節(jié)點。

RandomAccessFile的一個重要使用場景就是網(wǎng)絡(luò)請求中的多線程下載及斷點續(xù)傳。

構(gòu)造方法以及參數(shù)
構(gòu)造方法.png

mode中,有4中啟動的方式
"r" 以只讀方式打開。調(diào)用結(jié)果對象的任何 write 方法都將導(dǎo)致拋出 IOException。
"rw" 打開以便讀取和寫入。如果該文件尚不存在,則嘗試創(chuàng)建該文件。

"rws" 打開以便讀取和寫入,對于 "rw",還要求對文件的內(nèi)容或元數(shù)據(jù)的每個更新都同步寫入到底層存儲設(shè)備。
"rwd" 打開以便讀取和寫入,對于 "rw",還要求對文件內(nèi)容的每個更新都同步寫入到底層存儲設(shè)備。

RandomAccessFile使用

讀取文件內(nèi)容

            RandomAccessFile raf = new RandomAccessFile(file,"r");
            String s = null;
            while ((s = raf.readLine())!=null){
                System.out.println(s);
            }
            raf.close();

寫入文件內(nèi)容

String text = "寫入的內(nèi)容 \n";
            RandomAccessFile raf = new RandomAccessFile(file,"rw");
            raf.seek(12);   //改變寫入偏移的位置,從地12個字節(jié)的位置開始寫入
            raf.write(text.getBytes());
            raf.close();

注意:RandomAccessFile雖然可以設(shè)置了偏移的方法,但他不能實現(xiàn)中間插入的效果,如果你需要實現(xiàn)文本中間插入的話,要先將后面的文件內(nèi)容拷貝,然后寫入,最后在寫入的寫一行,將拷貝的東西復(fù)制回來。

七、對象的序列化與反序列化

什么是序列化和反序列化呢?這是針對對象來說的,因為我們在寫入文件的時候,常常因為要保存的是一個對象,也就是一個obj,但是里面的變量又很多,我們不可能挨個申明,一個個寫入,這時候,我們就可以使用對象的序列化與反序列化。

序列化就是對象到保存文件的過程。
反序列化就是從保存的文件,轉(zhuǎn)換為對象的過程。

我們使用ObjectOutputStream和ObjectInputStream 實現(xiàn)對象的序列化和反序列化。

File file = new File("test.txt");

        MyService ms = new MyService();
        try {
            OutputStream os = new FileOutputStream(file);
            //創(chuàng)建時,需要給予一個outputStream,這個很好理解,
            //因為對象操作肯定是字節(jié)操作,不能使用字符操作
            ObjectOutputStream oos = new ObjectOutputStream(os);
            oos.writeObject(ms);
            oos.close();
            os.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


        try {
            InputStream is = new FileInputStream(file);
            ObjectInputStream ios = new ObjectInputStream(is);
            MyService object = (MyService)ios.readObject();
            System.out.println(object.name);
            is.close();
            ios.close();    
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評論 6 540
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,275評論 3 428
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,904評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,368評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,736評論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,919評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,481評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,235評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,427評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,656評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,160評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,380評論 2 379

推薦閱讀更多精彩內(nèi)容