IO技術(shù)主要的作用是解決設(shè)備與設(shè)備之間的數(shù)據(jù)傳輸問題。
File類
sun使用了一個File類描述了文件或者文件夾的,F(xiàn)ile類可以描述一個文件或者一個文件夾。
File類的構(gòu)造方法:
File(String pathname)? 指定文件或者文件夾的路徑創(chuàng)建一個File對象
File(File parent, String child) 根據(jù)parent抽象路徑名和child路徑名字符串創(chuàng)建一個新File實例
路徑問題:
絕對路徑:該文件在硬盤上的完整路徑,絕對路徑一般都是以盤符開頭的。
相對路徑:? 相對路徑就是資源文件相對于當前程序所在的路徑。
. 當前路徑
.. 上一級路徑
注意: 如果程序當前所在的路徑與資源文件不是在同一個盤下面,是沒法寫相對路徑的。
File類的常用方法:
創(chuàng)建
createNewFile()——在指定位置創(chuàng)建一個空文件,成功就返回true,如果已存在就不創(chuàng)建然后返回false;
mkdir()——創(chuàng)建一個單級文件夾;
mkdirs()——創(chuàng)建多級文件夾;
dir = new File("F:\\aa\\bb");
System.out.println("創(chuàng)建多級文件夾:"+ dir.mkdirs());
renameTo(File dest)——如果目標文件與源文件是在同一個路徑下,那么renameTo的作用是重命名,如果目標文件與源文件不是在同一個路徑下,那么renameTo的作用就是剪切,而且還不能操作文件夾;
File file = new File("F:\\aa");
File destFile = new File("F:\\bb");
System.out.println("重命名成功嗎?"+file.renameTo(destFile)) ;
刪除
delete()——刪除文件或一個空文件夾,成功返回true,失敗返回false;
deleteOnExit() ——JVM退出的時候刪除文件;
判斷
exists()——文件或文件夾是否存在;
isFile()——是否是一個文件,如果不存在,則始終為false;
isDirectory()——是否是一個目錄,如果不存在,則始終為false;
isHidden()——是否是一個隱藏的文件或是否是隱藏的目錄;
isAbsolute()——測試此抽象路徑名是否為絕對路徑名;
獲取
getName()——獲取文件或文件夾的名稱;
getPath()——返回絕對路徑;
getAbsolutePath()——獲取文件的絕對路徑,與文件是否存在沒關(guān)系;
length()——獲取文件的大?。ㄗ止?jié)數(shù)),如果文件不存在則返回0L,如果是文件夾也返回0L;
getParent()——獲取文件的父路徑;
lastModified() ——獲取最后一次被修改的時間;
文件夾相關(guān)
static File[ ] listRoots()——列出所有的根目錄(Window中就是所有系統(tǒng)的盤符);
list()——把當前文件夾下面的所有子文件名與子文件夾名存儲到一個String類型的數(shù)組中返回;
listFiles()——把當前文件夾下面的所有子文件與子文件夾都使用了一個FIle對象描述,然后把這些File對象存儲到一個FIle數(shù)組中返回;
list(FilenameFilter filter)——返回指定當前目錄中符合過濾條件的子文件或子目錄。
listFiles(FilenameFilter filter)——返回指定當前目錄中符合過濾條件的子文件或子目錄。
// 自定義一個文件名過濾器
class MyFilter implements FilenameFilter{
? ? ?@Override
? ? ?public boolean accept(File dir, String name) {
? ? return name.endsWith(".java");
? ? }
}
IO流分類
如果是按照數(shù)據(jù)的流向劃分
輸入流
輸出流
如果按照處理的單位劃分
字節(jié)流: 字節(jié)流讀取得都是文件中二進制數(shù)據(jù),讀取到二進制數(shù)據(jù)不會經(jīng)過任何的處理。
字符流: 字符流讀取的數(shù)據(jù)是以字符為單位的。字符流也是讀取文件中的二進制數(shù)據(jù),不過會把這些二進制數(shù)據(jù)轉(zhuǎn)換成我們能識別的字符。
字符流 = 字節(jié)流 + 解碼
輸入字節(jié)流
--------| InputStream 所有輸入字節(jié)流的基類抽象類
--------------| FileInputStream 讀取文件數(shù)據(jù)的輸入字節(jié)流
--------------| BufferedInputStream 緩沖輸入字節(jié)流,緩沖輸入字節(jié)流的出現(xiàn)主要是為了提高讀取文件數(shù)據(jù)的效率。其實該類內(nèi)部只不過是維護了一個8kb的字節(jié)數(shù)組而已
使用FileInputStream讀取文件數(shù)據(jù)的步驟
1. 找到目標文件
2. 建立數(shù)據(jù)的輸入通道
3. 讀取文件中的數(shù)據(jù)
4. 關(guān)閉資源
使用BufferedInputStream的步驟?
1. 找到目標文件
2. 建立數(shù)據(jù)的輸入通道
3. 建立緩沖輸入字節(jié)流流
4. 關(guān)閉資源
注意: 凡是緩沖流都不具備讀寫文件的能力
輸出字節(jié)流
--------| OutputStream 是所有輸出字節(jié)流的父類,抽象類
-------------| FileOutStream 向文件輸出數(shù)據(jù)的輸出字節(jié)流
-------------| Bufferedoutputstream 緩沖輸出字節(jié)流,BufferedOutputStream出現(xiàn)的目的是為了提高寫數(shù)據(jù)的效率,內(nèi)部也是維護了一個8kb的字節(jié)數(shù)組而已
FileOutputStream如何使用呢
1. 找到目標文件
2. 建立數(shù)據(jù)的輸出通道
3. 把數(shù)據(jù)轉(zhuǎn)換成字節(jié)數(shù)組寫出
4. 關(guān)閉資源
FileOutputStream要注意的細節(jié)
1. 使用FileOutputStream 的時候,如果目標文件不存在,那么會自動創(chuàng)建目標文件對象
2. 使用FileOutputStream寫數(shù)據(jù)的時候,如果目標文件已經(jīng)存在,那么會先清空目標文件中的數(shù)據(jù),然后再寫入數(shù)據(jù)
3.使用FileOutputStream寫數(shù)據(jù)的時候,,如果目標文件已經(jīng)存在,需要在原來數(shù)據(jù)基礎(chǔ)上追加數(shù)據(jù)的時候,應該使用new FileOutputStream(file,true)構(gòu)造函數(shù),第二參數(shù)為true
4.使用FileOutputStream的write方法寫數(shù)據(jù)的時候,雖然接收的是一個int類型的數(shù)據(jù),但是真正寫出的只是一個字節(jié)的數(shù)據(jù),只是把低八位的二進制數(shù)據(jù)寫出,其他二十四位數(shù)據(jù)全部丟棄。
使用BufferedOutputStream的步驟
1. 找到目標文件
2. 建立數(shù)據(jù)的輸出通道
3. 把數(shù)據(jù)寫出
4. 關(guān)閉資源
BufferedOutputStream 要注意的細節(jié)
使用BufferedOutStream寫數(shù)據(jù)的時候,它的write方法是是先把數(shù)據(jù)寫到它內(nèi)部維護的字節(jié)數(shù)組中,如果需要把數(shù)據(jù)真正的寫到硬盤上面,需要調(diào)用flush方法或者是close方法、 或者是內(nèi)部維護的字節(jié)數(shù)組已經(jīng)填滿數(shù)據(jù)
回憶
字符流: 字符流會把讀取到的二進制的數(shù)據(jù)進行對應的編碼與解碼工作。? 字符流 = 字節(jié)流 + 編碼(解碼)
輸入字符流
----- | Reader 輸入字符流的基類,抽象類
-------------| FileReader 讀取文件的輸入字符流
-------------| BufferedReader? 緩沖輸入字符流,出現(xiàn)的目的是為了提高讀取文件的效率和拓展了FileReader的功能,其實該類內(nèi)部也是維護了一個字符數(shù)組;
FileReader的用法
1. 找到目標文件
2. 建立數(shù)據(jù)的輸入通道
3. 讀取數(shù)據(jù)
4. 關(guān)閉資源
輸出字符流
------| Writer 輸出字符流的基類,抽象類
-----------| FileWriter 向文件數(shù)據(jù)數(shù)據(jù)的輸出字符流
-----------|BufferedWriter 緩沖輸出字符流,提高FileWriter的寫數(shù)據(jù)效率與拓展FileWriter的功能。BufferedWriter內(nèi)部只不過是提供了一個8192長度的字符數(shù)組作為緩沖區(qū)而已,拓展了FileWriter的功能。
FileWriter的使用步驟
1. 找到目標文件
2. 建立數(shù)據(jù)輸出通道
3. 寫出數(shù)據(jù)
4. 關(guān)閉資源
FileWriter要注意的事項
1. 使用FileWriter寫數(shù)據(jù)的時候,F(xiàn)ileWriter內(nèi)部是維護了一個1024個字符的數(shù)組,寫數(shù)據(jù)的時候會先寫入到它內(nèi)部維護的字符數(shù)組中,如果需要把數(shù)據(jù)真正寫到硬盤上,需要調(diào)用flush或者是close方法或者是填滿了內(nèi)部的字符數(shù)組;
2. 使用FileWriter的時候,如果目標文件不存在,那么會自動創(chuàng)建目標文件;
3.使用FileWriter的時候, 如果目標文件已經(jīng)存在了,那么默認情況會先清空文件中的數(shù)據(jù),然后再寫入數(shù)據(jù),如果需要在原來的基礎(chǔ)上追加數(shù)據(jù)需要使用“new FileWriter(File , boolean)”的構(gòu)造方法,第二參數(shù)為true。
對象的輸入輸出流?
對象的輸入輸出流的主要作用是用于寫對象的信息與讀取對象的信息,對象信息一旦寫到文件上那么對象的信息就可以做到持久化了。
對象的輸出流:ObjectOutputStream
對象的輸入流: ObjectInputStream
對象輸入輸出流要注意的細節(jié)
1. 如果對象需要被寫出到文件上,那么對象所屬的類必須要實現(xiàn)Serializable接口。 Serializable接口沒有任何的方法,是一個標識接口而已;
2. 對象的反序列化創(chuàng)建對象的時候并不會調(diào)用到構(gòu)造方法;
3. serialVersionUID 是用于記錄class文件的版本信息的,serialVersionUID這個數(shù)字是通過一個類的類名、成員、包名、工程名算出的一個數(shù)字。使用ObjectInputStream反序列化的時候,ObjectInputStream會先讀取文件中的serialVersionUID,然后與本地的class文件的serialVersionUID進行對比,如果這兩個id不一致,那么反序列化就失敗了。
4. 如果序列化與反序列化的時候可能會修改類的成員,那么最好一開始就給這個類指定一個serialVersionUID,如果一類已經(jīng)指定的serialVersionUID,然后在序列化與反序列化的時候,jvm都不會再自己算這個class的serialVersionUID了。
5. 如果一個對象某個數(shù)據(jù)不想被序列化到硬盤上,可以使用關(guān)鍵字transient修飾。
7. 如果一個類維護了另外一個類的引用,那么另外一個類也需要實現(xiàn)Serializable接口。
轉(zhuǎn)換流
輸入字節(jié)流的轉(zhuǎn)換流:InputStreamReader
輸出字節(jié)流的轉(zhuǎn)換流:OutputStreamWriter
轉(zhuǎn)換流的作用
1. 如果目前所獲取到的是一個字節(jié)流需要轉(zhuǎn)換字符流使用,這時候就可以使用轉(zhuǎn)換流。
? ? ?字節(jié)流----> 字符流
2. 使用轉(zhuǎn)換流可以指定編碼表進行讀寫文件。