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