一、File
1.1 IO的概述
回想之前寫過的程序,數據都是在內存中,一旦程序運行結束,這些數據都沒有了,等下次再想使用這些數據,可是已經沒有了。那怎么辦呢?能不能把運算完的數據都保存下來,下次程序啟動的時候,再把這些數據讀出來繼續使用呢?其實要把數據持久化存儲,就需要把內存中的數據存儲到內存以外的其他持久化設備(硬盤、光盤、U盤等)上。
當需要把內存中的數據存儲到持久化設備上這個動作稱為輸出(寫)Output操作。當把持久設備上的數據讀取到內存中的這個動作稱為輸入(讀)Input操作。因此我們把這種輸入和輸出動作稱為IO操作。
1.2 File類
API對File類的描述:File文件和目錄路徑名的抽象表示形式。即,Java中把文件或者目錄(文件夾)都封裝成File對象。也就是說如果我們要去操作硬盤上的文件,或者文件夾只要找到File這個類即可。
1.2.1 File屬性
static String |
pathSeparator |
static char |
pathSeparatorChar |
static String |
separator |
static char |
separatorChar |
不同的操作系統,路徑的分隔符也會不一樣。Windows的為“\”,Linux 的為“/”。
1.2.2 File 的構造器:
File(String pathname) :通過將給定路徑名字符串轉換為抽象路徑名來創建一個新 File 實例。
File(File parent, String child) :根據 parent 抽象路徑名和 child 路徑名字符串創建一個新 File 實例。
File(String parent, String child) :根據 parent 路徑名字符串和 child 路徑名字符串創建一個新 File 實例。
File(URI uri) : 通過將給定的 file: URI 轉換為一個抽象路徑名來創建一個新的 File 實例。
1.3.3 File的常用方法
1.獲取該類的相關信息:
A)getAbsoluteFile() :返回此抽象路徑名的絕對路徑名形式。
B)getAbsolutePath() :返回此抽象路徑名的絕對路徑名字符串。
C)getCanonicalFile():返回此抽象路徑名的規范形式。
D)getCanonicalPath():返回此抽象路徑名的規范路徑名字符串
E)getName():返回由此抽象路徑名表示的文件或目錄的名稱。
F)getPath():將此抽象路徑名轉換為一個路徑名字符串。
G)getParent() :返回此抽象路徑名父目錄的路徑名字符串;如果此路徑名沒有指定父目錄,則返回 null。
H)getParentFile():返回此抽象路徑名父目錄的抽象路徑名;如果此路徑名沒有指定父目錄,則返回 null。
I)length():返回由此抽象路徑名表示的文件的長度。
import java.io.File; import java.io.IOException; public class Test2 { public static void main(String[] args) throws IOException { File file =new File("F\\IOTest\\a.txt");//第一個\為轉移字符 System.out.println(file.getName()); System.out.println(file.getPath()); System.out.println(file.getAbsolutePath()); System.out.println(file.getCanonicalPath()); //此處需要拋異常 System.out.println(file.getParent()); System.out.println(file.length()); //該文件對象實際並不存在 } }
運行結果:
a.txt F\IOTest\a.txt F:\eclipse-workspace\IOStream\F\IOTest\a.txt F:\eclipse-workspace\IOStream\F\IOTest\a.txt F\IOTest 0
2.新建和刪除
a) (boolean) createNewFile:當且僅當不存在具有此抽象路徑名指定名稱的文件時,不可分地創建一個新的空文件。
b) (boolean)delete():刪除此抽象路徑名表示的文件或目錄。
c) (boolean)exists():測試此抽象路徑名表示的文件或目錄是否存在。
d) (boolean)isDirectory():測試此抽象路徑名表示的文件是否是一個目錄。
e) (boolean) isFile(): 測試此抽象路徑名表示的文件是否是一個標准文件。
f) (boolean)mkdir():創建此抽象路徑名指定的目錄。
g) (boolean)mkdirs(): 創建此抽象路徑名指定的目錄,包括所有必需但不存在的父目錄。
3.文件的獲取:
a)(String[])list():返回一個字符串數組,這些字符串指定此抽象路徑名表示的目錄中的文件和目錄。
b)(File[])listFile():返回一個抽象路徑名數組,這些路徑名表示此抽象路徑名表示的目錄中的文件。
File file1=new File("F:\\"); for(String str:file1.list()) { System.out.println(str); }
4.文件過濾器:
通過listFiles()方法,我們可以獲取到一個目錄下的所有文件和文件夾,但能不能對其進行過濾呢?比如我們只想要一個目錄下的指定擴展名的文件,或者包含某些關鍵字的文件夾呢?
我們是可以先把一個目錄下的所有文件和文件夾獲取到,並遍歷當前獲取到所有內容,遍歷過程中在進行篩選,但是這個動作有點麻煩,Java給我們提供相應的功能來解決這個問題。
查閱File類的API,在查閱時發現File類中重載的listFiles方法,並且接受指定的過濾器。
(File[ ])listFiles(FilenameFilter filter):返回抽象路徑名數組,這些路徑名表示此抽象路徑名表示的目錄中滿足指定過濾器的文件和目錄。
public interface FilenameFilter:實現此接口的類實例可用於過濾器文件名。Abstract Window Toolkit 的文件對話框組件使用這些實例過濾 File 類的 list 方法中的目錄清單,該接口只有一個抽象方法。
public interface FilenameFilter { boolean accept(File dir, String name);
dir:the directory in which the file was found.
name :the name of the file.
(File[ ])listFiles(FileFilter filter) :返回一個抽象路徑名數組,這些路徑名表示此抽象路徑名表示的目錄中的文件。
public abstract class FileFilter { public abstract boolean accept(File f); public abstract String getDescription(); }
二、字節流
2.1字節輸出流OutputStream
OutputStream此抽象類,是表示輸出字節流的所有類的超類。操作的數據都是字節,定義了輸出字節流的基本共性功能方法。由於是字節byte型,輸出范圍為[-128,127)。OutputStream有很多子類,其中子類FileOutputStream可用來寫入數據到文件。
FileOutputStream類,即文件輸出流,是用於將數據寫入 File的輸出流。
以下為OutputStream的方法:
(abstract void)write(int b):將指定的字節寫入此輸出流。向輸出流寫入一個字節。要寫入的字節是參數 b 的八個低位。b 的 24 個高位將被忽略。
write(byte[] b, int off, int len):將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此輸出流。
write(byte[] b):將 b.length 個字節從指定的 byte 數組寫入此輸出流。
flush():刷新此輸出流並強制寫出所有緩沖的輸出字節。
close():關閉此輸出流並釋放與此流有關的所有系統資源。
2.2字節輸入流InputStream
(abstract void)read(int b):從輸入流中讀取數據的下一個字節,如果下一個為空,則輸出-1。
read(byte[ ] b):從輸入流中讀取一定的字節數,並儲存在緩沖區byte[ ] b 中。
public static void main(String[] args) throws IOException { File file =new File("F:\\IOTest\\a.txt");//第一個\為轉移字符 FileOutputStream fos=new FileOutputStream(file); fos.write("Hello,World".getBytes()); fos.flush(); fos.close(); FileInputStream fis =new FileInputStream(file); byte[] b=new byte[5]; System.out.println(fis.read(b)); System.out.println((char)fis.read()); System.out.println(Arrays.toString(b)); System.out.println(Arrays.toString(getChar(b))); fis.close(); } public static char[] getChar(byte[] bs) { int len=bs.length; char[] as=new char[len]; for(int i=0;i<len;i++) { as[i]=(char)bs[i]; } return as;
}
輸出結果:
5 , [72, 101, 108, 108, 111] [H, e, l, l, o]
三、字符流
在字節流的操作過程中可以操作所有數據,可是當我們操作的文件中有中文字符時,就需要使用字符流進行操作。
3.1字符輸入流Reader
我們讀取擁有中文的文件時,使用的字節流在讀取,那么我們讀取到的都是一個一個字節。只要把這些字節去查閱對應的編碼表,就能夠得到與之對應的字符。API中是否給我們已經提供了讀取相應字符的功能流對象,Reader,讀取字符流的抽象超類。
(int ) read():讀取單個字符
(int) read(char[] cbuf): 將字符讀入數字中。
3.1.1 FileReader
查閱FileInputStream的API,發現FileInputStream 用於讀取諸如圖像數據之類的原始字節流。要讀取字符流,請考慮使用 FileReader。
打開FileReader的API介紹。用來讀取字符文件的便捷類。此類的構造方法假定默認字符編碼和默認字節緩沖區大小都是適當的
構造方法:
FileReader(File files):在給定從中讀取數據的 File 的情況下創建一個新 FileReader。
FileReader(String filesName):在給定從中讀取數據的文件名的情況下創建一個新 FileReader
3.2字符輸出流Writer
既然有專門用於讀取字符的流對象,那么肯定也有寫的字符流對象,查閱API,發現有一個Writer類,Writer是寫入字符流的抽象類。其中描述了相應的寫的動作。
3.2.1 FileWriter
查閱FileOutputStream的API,發現FileOutputStream 用於寫入諸如圖像數據之類的原始字節的流。要寫入字符流,請考慮使用 FileWriter。
打開FileWriter的API介紹。用來寫入字符文件的便捷類。此類的構造方法假定默認字符編碼和默認字節緩沖區大小都是可接受的。
構造方法
public static void main(String[] args) throws IOException{ FileWriter fw=new FileWriter("F:\\IOTest\\a.txt"); fw.write("Hello World,好好學習,天天向上"); fw.flush(); fw.close(); FileReader fr=new FileReader("F:\\IOTest\\a.txt"); int a=0; while((a=fr.read())!=-1) { System.out.print((char)a); } fr.close(); }
flush和close的作用:
close():關閉此流,但要先刷新它。
flush():刷新該流的緩沖。
flush():將流中的緩沖區緩沖的數據刷新到目的地中,刷新后,流還可以繼續使用。
close():關閉資源,但在關閉前會將緩沖區中的數據先刷新到目的地,否則丟失數據,然后在關閉流。流不可以使用。如果寫入數據多,一定要一邊寫一邊刷新,最后一次可以不刷新,由close完成刷新並關閉。