Java基礎(chǔ)知識(shí)16-I/O流2


File 類

盡管 java.io 定義的大多數(shù)類用于操作流, 但 File 類卻不是.

File 類沒有指定如何從文件檢索信息以及如何向文件中存儲(chǔ)信息, 但是描述了文件本身的屬性.File 對(duì)象用于獲取和操作與磁盤文件關(guān)聯(lián)的信息, 例如權(quán)限, 時(shí)間, 日期以及目錄路徑, 并且還可以瀏覽子目錄層次.

在許多程序中, 文件是主要的數(shù)據(jù)源和目標(biāo). 盡管在 applet 中, 由于安全原因, 使用文件有一些限制, 但是文件仍然是存儲(chǔ)永久信息以及共享信息的主要資源.

下面的構(gòu)造函數(shù)可以用于創(chuàng)建 file 對(duì)象:

File(String dirPath)
File(String dirPath, String filename)
File(File dirObj, String filename)
File(URI uriObj)

其中, dirPath 是文件的路徑名; filename 是文件或子目錄的名稱; uriObj 是指定目錄的 File 對(duì)象; uriObj 是描述文件的URI對(duì)象.

給出一些例子:

File f1 = new File("/");
File f2 = new File("/", "aaa.bat");
File f3 = new File(f1, "bbb.bat");

注意: Java 使用介于UNIX 和 Windows 約定之間的路徑分隔符. 如果在Windows 版本的java中使用正斜杠(/), 那么路徑仍然會(huì)被正確解析.
請(qǐng)記住, 如果使用 Windows 約定的反斜杠(\), 那么在字符串中需要使用轉(zhuǎn)義序列(\\).

File 類定義了獲取 File 對(duì)象中標(biāo)準(zhǔn)屬性的方法. 例如, getName() 方法返回文件的名稱; getParent() 方法返回父目錄名; 并且如果文件存在, exists()方法將返回true, 否則返回false.

大家可以點(diǎn)擊此鏈接來(lái)查看API

流類

InputStream 和 OutputStream 針對(duì)字節(jié)流而設(shè)計(jì), Reader 和 Writer 針對(duì)字符流而設(shè)計(jì). 字節(jié)流類 和 字符流類形成了不同的層次.

通常, 當(dāng)操作字符或字符串時(shí), 應(yīng)當(dāng)使用字符流; 當(dāng)操作字節(jié)或其他二進(jìn)制對(duì)象時(shí), 應(yīng)當(dāng)使用字節(jié)流.

字節(jié)流

字節(jié)流類為處理面向字節(jié)的 I/O 提供了豐富的環(huán)境. 字節(jié)流可以用于任意類型的對(duì)象, 包括二進(jìn)制數(shù)據(jù).

1.InputStream類

定義了java的字節(jié)輸入模型, 并且還實(shí)現(xiàn)了 AutoCloseable 和 Closeable 接口. 當(dāng)發(fā)生 I/O 錯(cuò)誤時(shí), 該類中的大部分都會(huì)拋出 IOException 異常.

方 法 描 述
int available() 返回當(dāng)前可讀取的輸入字節(jié)數(shù)
void close() 關(guān)閉輸入源.
void mark(int numBytes) 在輸入流的當(dāng)前位置放置標(biāo)記, 該標(biāo)記在讀入 numBytes 個(gè)字節(jié)之前一直都有效
boolean markSupported() 如果調(diào)用流支持 mark() 或 reset() 方法,就返回true
int read() 返回代表下一個(gè)可用字節(jié)的整數(shù). 當(dāng)?shù)竭_(dá)文件末尾時(shí), 返回-1
int read(byte buffer[]) 嘗試讀取buffer.length個(gè)字節(jié)到buffer中, 并返回實(shí)際成功讀取的字節(jié)數(shù). 如果到達(dá)文件末尾, 就返回-1
int read(byte buffer[], int offset, int numBytes) 嘗試讀取 numBytes 個(gè)字節(jié)到 buffer中, 從 buffer[offset] 開始保存讀取的字節(jié), 該方法返回成功讀取的字節(jié)數(shù); 如果到達(dá)文件末尾, 就返回-1
void reset() 將輸入指針重置為前面設(shè)置的標(biāo)記
long skip(long numBytes) 忽略(即跳過(guò)) numBytes個(gè)字節(jié)的輸入, 返回實(shí)際忽略的字節(jié)數(shù)
2.OutpuStream類

定義流字節(jié)輸出的抽象類, 實(shí)現(xiàn)了 AutoCloseable Closeable以及 Flushable接口.

方 法 描 述
void close() 關(guān)閉輸出流.
void flush() 刷新輸出緩沖區(qū)
void writer(int b) 向輸出流中寫入單個(gè)字節(jié).
void writer(byte buffer[]) 向輸出流中寫入一個(gè)完整的字節(jié)數(shù)組.
void writer(byte buffer[], int offset, int numBytes) 將buffer數(shù)組從buffer[offset]開始的numBytes 個(gè)字節(jié)寫入輸出流中.
3.FileInputStream 類

兩個(gè)常用的構(gòu)造函數(shù)

FileInputStream(String filePath)
FileInputStream(File fileObj)

這兩個(gè)構(gòu)造函數(shù)都會(huì)拋出 FileNotFoundException 異常. 其中, filePath 是文件的完整路徑名, fileObj 是描述文件的File 對(duì)象.

下面的例子創(chuàng)建了兩個(gè) FileInputStream 對(duì)象, 它們使用相同的磁盤文件, 并且分別使用兩個(gè)構(gòu)造函數(shù)創(chuàng)建的:

FileInputStream f0 = new FileInputStream("/abc.bat");

File f = new File("/abc.bat");
FileInputStream f1 = new FileInputStream(f);

盡管第一個(gè)構(gòu)造函數(shù)可能更常用, 但是使用第二個(gè)構(gòu)造函數(shù), 在將文件附加到輸入流之前, 可以使用 File 類的方法對(duì)象進(jìn)行進(jìn)一步的檢查.

當(dāng)創(chuàng)建 FileInputStream 對(duì)象時(shí), 還可以為讀取而打開了.

下面的例子顯式了如何讀取單個(gè)字節(jié), 整個(gè)字節(jié)字節(jié)數(shù)組以及字節(jié)數(shù)組的一部分.

public class FileInputStreamDemo {
    public static void main(String[] args) {
        int size;
        int i;
        try(FileInputStream f = new FileInputStream("FileInputStream.java")) {
            System.out.println("Total Available Bytes: " + (size = f.available()));//available() 獲取剩余的字節(jié)數(shù)量

            int n = size / 40;
            for (i = 0; i < n; i++) {
                System.out.println((char) f.read()); //返回代表下一個(gè)可用字節(jié)的整數(shù). 當(dāng)?shù)竭_(dá)文件末尾時(shí), 返回-1
            }

            byte b[] = new byte[n];
            StringBuffer sb = new StringBuffer();
            while (f.read(b) != -1) {
                sb.append(new String(b, "UTF-8"));
            }
            System.out.println(sb.toString());

            b = new byte[n];
            sb = new StringBuffer();
            while (f.read(b, 0, n) != -1) {
                sb.append(new String(b, "UTF-8"));
            }
            System.out.println(sb.toString());

        } catch (IOException e) {
            System.out.println("I/O Error: " + e);
        }
    }
}
4.FileOutputStream 類

創(chuàng)建能夠用于向文件中寫入字節(jié)的OutputStream 對(duì)象。 該類實(shí)現(xiàn)了AutoCloseable, Closeable 以及 Flushable 接口, 它的4個(gè)構(gòu)造函數(shù)如下所示:

FileOutputStream(String filePath)
FileOutputStream(File file)
FileOutputStream(String filePath, boolean append)
FileOutputStream(File fileObj, boolean append)

它們都可能拋出 FileNotFoundException 異常. 其中, filePath 是文件的完整路徑, fileObj是描述文件的File 對(duì)象. 如果 append 為true, 就以追加方式打開文件.

FileOutputStream 對(duì)象的創(chuàng)建不依賴于已經(jīng)存在的文件. 當(dāng)創(chuàng)建對(duì)象時(shí), FileOutputStream 會(huì)在打開文件之前創(chuàng)建文件. 當(dāng)創(chuàng)建 FileOutputStream 對(duì)象時(shí), 如果試圖打開只讀文件, 會(huì)拋出異常.

public class FileOutputStream {
    public static void main(String[] args) {
        String source = "Now is the time for all good men\n" +
                " to come to the aid of their country\n" +
                " and pay their due taxes.";
        byte buf[] = source.getBytes();

        try (java.io.FileOutputStream f0 = new java.io.FileOutputStream("a.txt");
             java.io.FileOutputStream f1 = new java.io.FileOutputStream("b.txt");
             java.io.FileOutputStream f2 = new java.io.FileOutputStream("c.txt")){

            for (int i = 0; i < buf.length; i += 2) f0.write(buf[i]);

            f1.write(buf);

            f2.write(buf, buf.length - buf.length/4, buf.length/4);


        } catch (IOException e) {
            System.out.println("An I/O Error Occurred");
        }
    }
}

緩沖的字節(jié)流

1.BufferedInputStream 類

緩沖 I/O 是很常見的性能優(yōu)化手段. java 的 BufferedInputStream 類允許將任何 InputStream 對(duì)象封裝到緩沖流中以提高性能.

BufferedInputStream 類有兩個(gè)構(gòu)造函數(shù):

BufferedInputStream(InputStream inputStream)
BufferedInputStream(InputStream inputStream, int bufSize)

第一種形式使用默認(rèn)緩沖區(qū)大小(8192字節(jié))創(chuàng)建緩沖流. 在第二種形式中, 緩沖器大小是由 bufSize 傳遞的. 使緩沖區(qū)大小等于內(nèi)存頁(yè)面, 磁盤塊等大小的整數(shù)倍, 可以明顯提高性能. 然而,這依賴于具體實(shí)現(xiàn).

最優(yōu)的緩沖區(qū)大小通常依賴于宿主操作系統(tǒng), 可用的內(nèi)存數(shù)量以及機(jī)器的配置.

為了充分利用緩沖, 不需要這么復(fù)雜. 比較好的緩沖大小大約是 8 192字節(jié), 并且對(duì)于 I/O 系統(tǒng)來(lái)說(shuō)既是附加比較小的緩沖區(qū), 也是一個(gè)好主意.

這樣的話, 低級(jí)的系統(tǒng)就可以對(duì)磁盤或網(wǎng)絡(luò)獲取多塊數(shù)據(jù), 并將結(jié)果存儲(chǔ)在緩沖區(qū)中. 因此, 即使正在從 InputStream 對(duì)象一次讀取一個(gè)字節(jié), 大部分時(shí)間也都是在操作訪問(wèn)速度很快的內(nèi)存.

2.BufferedOutputStream 類

除了增加 flush() 方法之外, BufferedOutputStream 與所有 OutputStream 類似, flush() 方法用于確保將數(shù)據(jù)緩沖區(qū)寫入被緩沖的流中. BufferedOutputStream 是通過(guò)減少系統(tǒng)實(shí)際寫數(shù)據(jù)的次數(shù)來(lái)提高性能的, 因此可能需要調(diào)用 flush() 方法, 從而要求立即寫入緩沖區(qū)的所有數(shù)據(jù).

下面是兩個(gè)構(gòu)造函數(shù):

BufferedOutputStream(OutputStream outputStream)
BufferedOutputStream(OutputStream outputStream, int bufSize)

第一種方式使用默認(rèn)緩沖區(qū)大小創(chuàng)建緩沖流. 第二種方式, 緩沖區(qū)大小是由 bufSize傳遞的.

PrintStream 類

實(shí)現(xiàn)了 Appendable, AutoCloseable, Closeable 以及 Flushable接口.

PrintStream(OutputStream outputStream)
PrintStream(OutputStream outputStream, boolean autoFlushingOn)
PrintStream(OutputStream outputStream, boolean autoFlushingOn, String charSet) throws UnsupportedEncodingException

在此, outpuStream 指定了用于接收輸出的打開的 OutputStream 對(duì)象. autoFlushingOn 參數(shù)控制每次寫入一個(gè)換行符或字節(jié)數(shù)組, 如果調(diào)用 println() 方法時(shí), 是否自定刷新輸出緩沖區(qū). 如果為true, 就自動(dòng)刷新; 如果為false, 就不自動(dòng)刷新. 第一個(gè)構(gòu)造函數(shù)不自動(dòng)刷新緩沖區(qū). 可以通過(guò) charSet 傳遞的名稱來(lái)指定字符編碼.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末培愁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖氢妈,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哎榴,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡酬凳,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門遭庶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)宁仔,“玉大人,你說(shuō)我怎么就攤上這事峦睡◆嵘唬” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵榨了,是天一觀的道長(zhǎng)煎谍。 經(jīng)常有香客問(wèn)我,道長(zhǎng)龙屉,這世上最難降的妖魔是什么呐粘? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上作岖,老公的妹妹穿的比我還像新娘唆垃。我一直安慰自己,他們只是感情好鳍咱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布降盹。 她就那樣靜靜地躺著,像睡著了一般谤辜。 火紅的嫁衣襯著肌膚如雪蓄坏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天丑念,我揣著相機(jī)與錄音涡戳,去河邊找鬼。 笑死脯倚,一個(gè)胖子當(dāng)著我的面吹牛渔彰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播推正,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼恍涂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了植榕?” 一聲冷哼從身側(cè)響起再沧,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎尊残,沒想到半個(gè)月后炒瘸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡寝衫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年顷扩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片慰毅。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡隘截,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汹胃,到底是詐尸還是另有隱情婶芭,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布统台,位于F島的核電站雕擂,受9級(jí)特大地震影響啡邑,放射性物質(zhì)發(fā)生泄漏贱勃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望贵扰。 院中可真熱鬧仇穗,春花似錦、人聲如沸戚绕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)舞丛。三九已至耘子,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間球切,已是汗流浹背谷誓。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吨凑,地道東北人捍歪。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像鸵钝,于是被迫代替她去往敵國(guó)和親糙臼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

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

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法恩商,類相關(guān)的語(yǔ)法变逃,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法痕届,異常的語(yǔ)法韧献,線程的語(yǔ)...
    子非魚_t_閱讀 31,631評(píng)論 18 399
  • 一、流的概念和作用研叫。 流是一種有順序的锤窑,有起點(diǎn)和終點(diǎn)的字節(jié)集合,是對(duì)數(shù)據(jù)傳輸?shù)目偝苫虺橄笕侣<磾?shù)據(jù)在兩設(shè)備之間的傳輸...
    布魯斯不吐絲閱讀 10,039評(píng)論 2 95
  • 在經(jīng)過(guò)一次沒有準(zhǔn)備的面試后渊啰,發(fā)現(xiàn)自己雖然寫了兩年的android代碼,基礎(chǔ)知識(shí)卻忘的差不多了申屹。這是程序員的大忌绘证,沒...
    猿來(lái)如癡閱讀 2,841評(píng)論 3 10
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司哗讥,掛了不少嚷那,但最終還是拿到小米、百度杆煞、阿里魏宽、京東腐泻、新浪、CVTE队询、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,246評(píng)論 11 349
  • 這個(gè)夜晚派桩,有點(diǎn)難熬……
    罅舞茶閱讀 177評(píng)論 0 0