你真的以為了解java.io嗎 嘔心瀝血 絕對干貨 別把我移出首頁了


文章結構
1 flush的使用場景
2 一個java字節流,inputstream 和 outputstream的簡單例子
3 分別測試了可能拋出java.io.FileNotFoundException,java.io.FileNotFoundException: test (拒絕訪問。),java.io.FileNotFoundException: test.txt (系統找不到指定的文件。)的所有場景,你再也不怕java.io異常了
4 測試了flush的使用場景
5 給出了flush的源碼
6 提出了自己的兩個小疑問
 
1 flush的有效使用場景
outputstream中有flush()方法, 而inputstream沒有用到緩沖區,對於字節流來說,緩沖區就是一個byte數組,而OutputStream類的flush()卻什么也沒做,其實flush()是Flushable接口的方法,官方文檔的對該方法的注釋是“Flushes this output stream and forces any buffered output bytes to be written out.”。OutputStream方法實現了Flushable接口,而又什么也沒做,真是讓人一頭霧水,那么什么時候flush()才有效呢?當OutputStream是BufferedOutputStream時。當寫文件需要flush()的效果時,需要需要將FileOutputStream作為BufferedOutputStream構造函數的參數傳入,然后對BufferedOutputStream進行寫入操作,才能利用緩沖及flush()。查看BufferedOutputStream的源代碼,發現所謂的buffer其實就是一個byte[]。BufferedOutputStream的每一次write其實是將內容寫入byte[],當buffer容量到達上限時,會觸發真正的磁盤寫入。而另一種觸發磁盤寫入的辦法就是調用flush()了。
 
2一個java字節流,inputstream 和 outputstream的簡單例子
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class OutputStreamDemo {
    public static void main(String[] args) {
          try {

             // create a new output stream
             OutputStream os = new FileOutputStream("test.txt");

             // craete a new input stream
             InputStream is = new FileInputStream("test.txt");
             // write something
             os.write('A');

             // flush the stream but it does nothing
             os.flush();

             // write something else
             os.write('B');

             // read what we wrote
             System.out.println("" + is.available());

          } catch (Exception ex) {
             ex.printStackTrace();
          }


       }

}
說明我們的os.flush()什么也沒有做
其中  OutputStream os = new FileOutputStream("test.txt");將在我們項目下的根文件下建立一個TXT文件,FileOutputStream創建一個向具有指定名稱的文件中寫入數據的輸出文件流。創建一個新 FileDescriptor 對象來表示此文件連接。如果有安全管理器,則用 name 作為參數調用 checkWrite 方法。 如果該文件存在,但它是一個目錄,而不是一個常規文件;或者該文件不存在,但無法創建它;抑或因為其他某些原因而無法打開它,則拋出 FileNotFoundException,
3 測試java.io異常
當我們的String name定義為一個空字符串的時候 拋出如下異常
java.io.FileNotFoundException: 
    at java.io.FileOutputStream.open0(Native Method)
    at java.io.FileOutputStream.open(Unknown Source)
    at java.io.FileOutputStream.<init>(Unknown Source)
    at java.io.FileOutputStream.<init>(Unknown Source)
    at OutputStreamDemo.OutputStreamDemo.main(OutputStreamDemo.java:14)
 
當我們在根目錄下定義一個文件夾也名為test的文件夾時,會拋出如下異常
java.io.FileNotFoundException: test (拒絕訪問。)
    at java.io.FileOutputStream.open0(Native Method)
    at java.io.FileOutputStream.open(Unknown Source)
    at java.io.FileOutputStream.<init>(Unknown Source)
    at java.io.FileOutputStream.<init>(Unknown Source)
    at OutputStreamDemo.OutputStreamDemo.main(OutputStreamDemo.java:14)
當我們的FileOutputStream("test.txt");和FileInputStream("test.txt");中的字符串不一致時會出現異常
java.io.FileNotFoundException: test.txt (系統找不到指定的文件。)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(Unknown Source)
    at java.io.FileInputStream.<init>(Unknown Source)
    at java.io.FileInputStream.<init>(Unknown Source)
    at OutputStreamDemo.OutputStreamDemo.main(OutputStreamDemo.java:17)
我們這里用了 os.write('A');這里的'A'是int類型的
4 測試了flush的使用場景
OutputStream os = new FileOutputStream("test.txt");

             // craete a new input stream
             InputStream is = new FileInputStream("test.txt");
             // write something
             BufferedOutputStream bos = new BufferedOutputStream(os);
             bos.write('C');

             // flush the stream but it does nothing
             bos.flush();

             // write something else
             bos.write('B');
             bos.close();

如果我們不使用flush,也不使用close的話,則輸出結果為0
5 給出了flush的源碼

通過查看源碼,可以看到 BufferedOutputStream中的flush實現如下 BufferedOutputStream是同步的

public synchronized void flush() throws IOException {
        flushBuffer();
    out.flush();
    }
private void flushBuffer() throws IOException {
        if (count > 0) {
        out.write(buf, 0, count);
        count = 0;
        }
    }
    public void write(byte b[], int off, int len) throws IOException {
    if (b == null) {
        throw new NullPointerException();
    } else if ((off < 0) || (off > b.length) || (len < 0) ||
           ((off + len) > b.length) || ((off + len) < 0)) {
        throw new IndexOutOfBoundsException();
    } else if (len == 0) {
        return;
    }
    for (int i = 0 ; i < len ; i++) {
        write(b[off + i]);
    }
    }

6 提出了自己的兩個小疑問

我的小疑問:

1 小疑問 另外,在我使用editplus打開該文件的時候,我任然可以執行java命令重新對該文件進行寫入,這讓我想到了java的多線程的鎖及數據庫的鎖
也對,在我用editplus打開該文件的時候僅僅是執行讀取得權限,而其他應用程序是可以進行更改的
2 當我使用java程序更改該文件的時候,我在打開editplus窗口的時候,提示我the file has been modified by another programmer ,do you want to reload it.這說明editplus有一個監視器隨時在監視該文件的狀態


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM