閱讀428 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Java 筆記09

Module 10:I/O流(java如何實現與外界數據的交流)

Input/Output:指跨越出了JVM的邊界,與外界數據的源頭或者目標數據源進行數據交換。

              輸出

 

 


              輸入                  

 注意:輸入/輸出是針對JVM而言。

File類(java.io.*)可表示一個文件,也有可能是一個目錄(在JAVA中文件和目錄都屬於這個類中,而且區分不是非常的明顯)。

Java.io下的方法是對磁盤上的文件進行磁盤操作,但是無法讀取文件的內容。

注意:創建一個文件對象和創建一個文件在JAVA中是兩個不同的概念。前者是在虛擬機中創建了一個文件,但卻並沒有將它真正地創建到OS的文件係統中,隨著虛擬機的關閉,這個創建的對象也就消失了。而創建一個文件才是在係統中真正地建立一個文件。

例如:File f=new File(“11.txt”);//創建一個名為11.txt的文件對象

f.CreateNewFile();    //真正地創建文件

 

f.CreateMkdir():創建目錄

f.delete();刪除文件

f.deleteOnExit();在進程退出的時候刪除文件,這樣的操作通常用在臨時文件的刪除。

 

對於命令:File f2=new file(“d:\\abc\\789\\1.txt”)

這個命令不具備跨平台性,因為不同的OS的文件係統很不相同。

如果想要跨平台,在file類下有separtor(),返回鎖出平台的文件分隔符。

File.fdir=newFile(File.separator);

Stringstr=”abc”+File.separator+”789”;

使用文件下的方法的時候一定注意是否具備跨平台性。

 

List():顯示文件的名(相對路徑)

ListFiles():返回Files類型數組,可以用getName()來訪問到文件名。

使用isDirectory()和isFile()來判斷究竟是文件還是目錄。

 

練習:

寫一個javaTest程序,列出所有目錄下的*.java文件,把子目錄下的JAVA文件也打印出來。

 

使用I/O流訪問file中的內容。

JVM與外界通過數據通道進行數據交換。

分類:

按流分為輸入流和輸出流;

按傳輸單位分為字節流和字符流;

還可以分為節點流和過濾流。

節點流:負責數據源和程序之間建立連接;

過濾流:用於給節點增加功能。

過濾流的構造方式是以其他流位參數構造(這樣的設計模式稱為裝飾模式)。

 

字節輸入流:io包中的InputStream為所有字節輸入流的父類。

Int read();讀入一個字節(每次一個);

可先使用new  byte[]=數組,調用read(byte[] b)

read (byte[])返回值可以表示有效數;read(byte[])返回值為-1表示結束。

 

字節輸出流:io包中的OutputStream位所有字節輸入流的父類。

Write和輸入流中的read相對應。

 

在流中close()方法由程序員控製。因為輸入輸出流已經超越了VM的邊界,所以有時可能無法回收資源。

原則:凡是跨出虛擬機邊界的資源都要求程序員自己關閉,不要指望垃圾回收。

以Stream結尾的類都是字節流。

如果構造FileOutputStream的同時磁盤會建立一個文件。如果創建的文件與磁盤上已有的文件名重名,就會發生覆蓋。

用FileOutputStream中的boolean,則視,添加情況,將數據覆蓋重名文件還是將輸入內容放在文件的後麵。(編寫程序驗證)

 

DataOutputStream:輸入數據的類型。

因為每中數據類型的不同,所以可能會輸出錯誤。

所有對於:DataOutputStream

         DataInputStream

          兩者的輸入順序必須一致。

過濾流:

 bufferedOutputStream

 bufferedInputStream

用於給節點流增加一個緩衝的功能。
在VM的內部建立一個緩衝區,數據先寫入緩衝區,等到緩衝區的數據滿了之後再一次性寫出,效率很高。

使用帶緩衝區的輸入輸出流的速度會大幅提高,緩衝區越大,效率越高。(這是典型的犧牲空間換時間)

切記:使用帶緩衝區的流,如果數據數據輸入完畢,使用flush方法將緩衝區中的內容一次性寫入到外部數據源。用close()也可以達到相同的效果,因為每次close都會使用flush。一定要注意關閉外部的過濾流。

 

(非重點)管道流:也是一種節點流,用於給兩個線程交換數據。

PipedOutputStream

PipedInputStream

輸出流:connect(輸入流)

 

RondomAccessFile類允許隨機訪問文件

GetFilepoint()可以知道文件中的指針位置,使用seek()定位。

Mode(“r”:隨機讀;”w”:隨機寫;”rw”:隨機讀寫)

練習:寫一個類A,JAVAA file1 file2

file1要求是係統中已經存在的文件。File2是還沒有存在的文件。

執行完這個命令,那麼file2就是file1中的內容。

 

字符流:reader\write隻能輸純文本文件。

FileReader類:字符文件的輸出

 

字節流與字符流的區別:

字節流的字符編碼:

字符編碼把字符轉換成數字存儲到計算機中,按ASCii將字母映射為整數。

把數字從計算機轉換成相應的字符的過程稱為解碼。

編碼方式的分類:

ASCII(數字、英文):1個字符占一個字節(所有的編碼集都兼容ASCII)

ISO8859-1(歐洲):1個字符占一個字節

GB-2312/GBK:1個字符占兩個字節

Unicode: 1個字符占兩個字節(網絡傳輸速度慢)

UTF-8:變長字節,對於英文一個字節,對於漢字兩個或三個字節。

 

原則:保證編解碼方式的統一,才能不至於出現錯誤。

Io包的InputStreamread稱為從字節流到字符流的橋轉換類。這個類可以設定字符轉換方式。

OutputStreamred:字符到字節

Bufferread有readline()使得字符輸入更加方便。

在I/O流中,所有輸入方法都是阻塞方法。

Bufferwrite給輸出字符加緩衝,因為它的方法很少,所以使用父類printwrite,它可以使用字節流對象,而且方法很多。

 

練習:做一個記事本

swing/JfileChoose:getSelect file()

InputStreeamReader:把字節變為字符

JAVA中對字符串長無限製  bufferedReader(ir)

()

 

釋放鎖標記隻有在Synchronized代碼結束或者調用wait()。

注意鎖標記是自己不會自動釋放,必須有通知。

注意在程序中判定一個條件是否成立時要注意使用WHILE要比使用IF要嚴密。

WHILE會放置程序饒過判斷條件而造成越界。

補充知識:

suspend()是將一個運行時狀態進入阻塞狀態(注意不釋放鎖標記)。恢複狀態的時候用resume()。Stop()指釋放全部。

這幾個方法上都有Deprecated標誌,說明這個方法不推薦使用。

 

一般來說,主方法main()結束的時候線程結束,可是也可能出現需要中斷線程的情況。對於多線程一般每個線程都是一個循環,如果中斷線程我們必須想辦法使其退出。


如果主方法main()想結束阻塞中的線程(比如sleep或wait)

那麼我們可以從其他進程對線程對象調用interrupt()。用於對阻塞(或鎖池)會拋出例外InterruptedException。

這個例外會使線程中斷並執行catch中代碼。

 

多線程中的重點:實現多線程的兩種方式,Synchronized,以及生產者和消費者問題(ProducerConsumer.java文件)。

 

練習:

①  存車位的停開車的次序輸出問題;

②  寫兩個線程,一個線程打印1-52,另一個線程答應字母A-Z。打印順序為12A34B56C……5152Z。通過使用線程之間的通信協調關係。

注:分別給兩個對象構造一個對象o,數字每打印兩個或字母每打印一個就執行o.wait()。在o.wait()之前不要忘了寫o.notify()。

 

補充說明:通過Synchronized,可知Vector較ArrayList方法的區別就是Vector所有的方法都有Synchronized。所以Vector更為安全。

同樣:Hashtable較HashMap也是如此。

最後更新:2017-04-02 16:47:44

  上一篇:go Spring中應用反射機製淺析
  下一篇:go Log 開關