Java Stream、File和IO
讀取控制臺輸入
Java的控制臺輸入由System.in完成
為了獲得一個綁定控制臺的字符流,可以把System.in包裝在一個BufferedReader對象中來創建一個字符流
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedReader 對象創建後,我們便可以使用read()方法從控制臺讀取一個字符,或者用readLine()方法讀取一個字符串
從控制臺讀取多字符輸入
從BufferedReader對象讀取一個字符要使用read()方法
int read( ) throws IOException
每次調用read()方法,它從輸入流讀取一個字符並把該字符作為整數值返回。當流結束的時候返回-1。該方法拋出IOException。
下面的程序示範了用read()方法從控制臺不斷讀取字符直到用戶輸入“q”
// 使用 BufferedReader 在控制臺讀取字符 import java.io.*; public class BRRead { public static void main(String args[]) throws IOException { char c; // 使用 System.in 創建 BufferedReaderBufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("輸入字符, 按下 ‘q‘ 鍵退出。"); // 讀取字符 do { c = (char) br.read(); System.out.println(c); } while(c != ‘q‘); } }
從控制臺讀取字符串
從標準輸入讀取一個字符串需要使用BufferedReader的readLine()方法
String readLine( ) throws IOException
下面的程序讀取和顯示字符行直到你輸入了單詞“end”
// 使用 BufferedReader 在控制臺讀取字符 import java.io.*; public class BRReadLines { public static void main(String args[]) throws IOException { // 使用 System.in 創建 BufferedReader BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str; System.out.println("Enter lines of text."); System.out.println("Enter ‘end‘ to quit."); do { str = br.readLine(); System.out.println(str); } while(!str.equals("end")); } }
控制臺輸出
PrintStream繼承了OutputStream類,並且實現了方法write()。這樣write()也可以用來往控制臺寫操作
PrintStream定義write())的最簡單的格式:
void write(int byteval)
該方法將byteval的低八位字節寫到流中
import java.io.*; // 演示 System.out.write(). public class WriteDemo { public static void main(String args[]) { int b; b = ‘A‘; System.out.write(b); System.out.write(‘\n‘); } }
write()方法不經常使用,因為print()和println()方法用起來更方便
FileInputStream
該流用於從文件讀取數據,它的對象可以用關鍵字new來創建
有多種構造方法可用來創建對象
可以使用字符串類型的文件名來創建一個輸入流對象來讀取文件
InputStream f = new FileInputStream("C:/java/hello");
也可以使用一個文件對象來創建一個輸入流對象來讀取文件
File f = new File("C:/java/hello"); InputStream out = new FileInputStream(f);
創建了InputStream對象,就可以使用下面的方法來讀取流或者進行其他的流操作
1 | public void close() throws IOException{} 關閉此文件輸入流並釋放與此流有關的所有系統資源。拋出IOException異常。 |
2 | protected void finalize()throws IOException {} 這個方法清除與該文件的連接。確保在不再引用文件輸入流時調用其 close 方法。拋出IOException異常。 |
3 | public int read(int r)throws IOException{} 這個方法從 InputStream 對象讀取指定字節的數據。返回為整數值。返回下一字節數據,如果已經到結尾則返回-1。 |
4 | public int read(byte[] r) throws IOException{} 這個方法從輸入流讀取r.length長度的字節。返回讀取的字節數。如果是文件結尾則返回-1。 |
5 | public int available() throws IOException{} 返回下一次對此輸入流調用的方法可以不受阻塞地從此輸入流讀取的字節數。返回一個整數值。 |
FileOutputStream
該類用來創建一個文件並向文件中寫數據
如果該流在打開文件進行輸出前,目標文件不存在,那麽該流會創建該文件
有兩個構造方法可以用來創建FileOutputStream對象
使用字符串類型的文件名來創建一個輸出流對象
OutputStream f = new FileOutputStream("C:/java/hello")
也可以使用一個文件對象來創建一個輸出流來寫文件
File f = new File("C:/java/hello"); OutputStream f = new FileOutputStream(f);
創建OutputStream對象完成後,就可以使用下面的方法來寫入流或者進行其他的流操作
1 | public void close() throws IOException{} 關閉此文件輸入流並釋放與此流有關的所有系統資源。拋出IOException異常。 |
2 | protected void finalize()throws IOException {} 這個方法清除與該文件的連接。確保在不再引用文件輸入流時調用其 close 方法。拋出IOException異常。 |
3 | public void write(int w)throws IOException{} 這個方法把指定的字節寫到輸出流中。 |
4 | public void write(byte[] w) 把指定數組中w.length長度的字節寫到OutputStream中。 |
一個演示InputStream和OutputStream用法的例子
import java.io.*; public class fileStreamTest{ public static void main(String args[]){ try{ byte bWrite [] = {11,21,3,40,5}; OutputStream os = new FileOutputStream("test.txt"); for(int x=0; x < bWrite.length ; x++){ os.write( bWrite[x] ); // writes the bytes } os.close(); InputStream is = new FileInputStream("test.txt"); int size = is.available(); for(int i=0; i< size; i++){ System.out.print((char)is.read() + " "); } is.close(); }catch(IOException e){ System.out.print("Exception"); } } }
上面的程序首先創建文件test.txt,並把給定的數字以二進制形式寫進該文件,同時輸出到控制臺上
以上代碼由於是二進制寫入,可能存在亂碼,你可以使用以下代碼實例來解決亂碼問題
import java.io.*; public class fileStreamTest2{ public static void main(String[] args) throws IOException { File f = new File("a.txt"); FileOutputStream fop = new FileOutputStream(f); // 構建FileOutputStream對象,文件不存在會自動新建 OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8"); // 構建OutputStreamWriter對象,參數可以指定編碼,默認為操作系統默認編碼,windows上是gbk writer.append("中文輸入"); // 寫入到緩沖區 writer.append("\r\n"); //換行 writer.append("English"); // 刷新緩存沖,寫入到文件,如果下面已經沒有寫入的內容了,直接close也會寫入 writer.close(); //關閉寫入流,同時會把緩沖區內容寫入文件,所以上面的註釋掉 fop.close(); // 關閉輸出流,釋放系統資源 FileInputStream fip = new FileInputStream(f); // 構建FileInputStream對象 InputStreamReader reader = new InputStreamReader(fip, "UTF-8"); // 構建InputStreamReader對象,編碼與寫入相同 StringBuffer sb = new StringBuffer(); while (reader.ready()) { sb.append((char) reader.read()); // 轉成char加到StringBuffer對象中 } System.out.println(sb.toString()); reader.close(); // 關閉讀取流 fip.close(); // 關閉輸入流,釋放系統資源 } }
Java File類
Java文件類以抽象的方式代表文件名和目錄路徑名。該類主要用於文件和目錄的創建、文件的查找和文件的刪除等。
File對象代表磁盤中實際存在的文件和目錄。通過以下構造方法創建一個File對象。
用過給定的父抽象路徑名和子路徑名字符串創建一個新的File實例。
File(File parent, String child);
通過給定路徑名字符串轉換成抽象路徑名來創建一個新File實例
File(String pathname)
根據parent路徑名字符串和child路徑名字符串創建一個新File實例
File(String parent, String child)
通過將給定的file:URI轉換成一個抽象路徑名來創建一個新的File實例
File(URI uri)
創建File對象成功後,可以使用以下列表中的方法操作文件
1 | public String getName() 返回由此抽象路徑名表示的文件或目錄的名稱。 |
2 | public String getParent()、 返回此抽象路徑名的父路徑名的路徑名字符串,如果此路徑名沒有指定父目錄,則返回 null 。 |
3 | public File getParentFile() 返回此抽象路徑名的父路徑名的抽象路徑名,如果此路徑名沒有指定父目錄,則返回 null 。 |
4 | public String getPath() 將此抽象路徑名轉換為一個路徑名字符串。 |
5 | public boolean isAbsolute() 測試此抽象路徑名是否為絕對路徑名。 |
6 | public String getAbsolutePath() 返回抽象路徑名的絕對路徑名字符串。 |
7 | public boolean canRead() 測試應用程序是否可以讀取此抽象路徑名表示的文件。 |
8 | public boolean canWrite() 測試應用程序是否可以修改此抽象路徑名表示的文件。 |
9 | public boolean exists() 測試此抽象路徑名表示的文件或目錄是否存在。 |
10 | public boolean isDirectory() 測試此抽象路徑名表示的文件是否是一個目錄。 |
11 | public boolean isFile() 測試此抽象路徑名表示的文件是否是一個標準文件。 |
12 | public long lastModified() 返回此抽象路徑名表示的文件最後一次被修改的時間。 |
13 | public long length() 返回由此抽象路徑名表示的文件的長度。 |
14 | public boolean createNewFile() throws IOException 當且僅當不存在具有此抽象路徑名指定的名稱的文件時,原子地創建由此抽象路徑名指定的一個新的空文件。 |
15 | public boolean delete() 刪除此抽象路徑名表示的文件或目錄。 |
16 | public void deleteOnExit() 在虛擬機終止時,請求刪除此抽象路徑名表示的文件或目錄。 |
17 | public String[] list() 返回由此抽象路徑名所表示的目錄中的文件和目錄的名稱所組成字符串數組。 |
18 | public String[] list(FilenameFilter filter) 返回由包含在目錄中的文件和目錄的名稱所組成的字符串數組,這一目錄是通過滿足指定過濾器的抽象路徑名來表示的。 |
19 | public File[] listFiles() 返回一個抽象路徑名數組,這些路徑名表示此抽象路徑名所表示目錄中的文件。 |
20 | public File[] listFiles(FileFilter filter) 返回表示此抽象路徑名所表示目錄中的文件和目錄的抽象路徑名數組,這些路徑名滿足特定過濾器。 |
21 | public boolean mkdir() 創建此抽象路徑名指定的目錄。 |
22 | public boolean mkdirs() 創建此抽象路徑名指定的目錄,包括創建必需但不存在的父目錄。 |
23 | public boolean renameTo(File dest) 重新命名此抽象路徑名表示的文件。 |
24 | public boolean setLastModified(long time) 設置由此抽象路徑名所指定的文件或目錄的最後一次修改時間。 |
25 | public boolean setReadOnly() 標記此抽象路徑名指定的文件或目錄,以便只可對其進行讀操作。 |
26 | public static File createTempFile(String prefix, String suffix, File directory) throws IOException 在指定目錄中創建一個新的空文件,使用給定的前綴和後綴字符串生成其名稱。 |
27 | public static File createTempFile(String prefix, String suffix) throws IOException 在默認臨時文件目錄中創建一個空文件,使用給定前綴和後綴生成其名稱。 |
28 | public int compareTo(File pathname) 按字母順序比較兩個抽象路徑名。 |
29 | public int compareTo(Object o) 按字母順序比較抽象路徑名與給定對象。 |
30 | public boolean equals(Object obj) 測試此抽象路徑名與給定對象是否相等。 |
31 | public String toString() 返回此抽象路徑名的路徑名字符串。 |
下面的實例演示了File對象的使用
import java.io.File; public class DirList { public static void main(String args[]) { String dirname = "/java"; File f1 = new File(dirname); if (f1.isDirectory()) { System.out.println( "Directory of " + dirname); String s[] = f1.list(); for (int i=0; i < s.length; i++) { File f = new File(dirname + "/" + s[i]); if (f.isDirectory()) { System.out.println(s[i] + " is a directory"); } else { System.out.println(s[i] + " is a file"); } } } else { System.out.println(dirname + " is not a directory"); } } }
Java中的目錄
創建目錄
File類中有兩個方法可以用來創建文件夾:
- mkdir()方法創建一個文件夾,成功則返回true,失敗則返回false。失敗表明File對象指定的路徑已經存在,或者由於整個路徑還不存在,該文件夾不能被創建
- mkdirs()方法創建一個文件夾和它的所有父文件夾
下面的例子創建“/tmp/user/java/bin”文件夾:
import java.io.File; public class CreateDir { public static void main(String args[]) { String dirname = "/tmp/user/java/bin"; File d = new File(dirname); // 現在創建目錄 d.mkdirs(); } }
讀取目錄
一個目錄其實就是一個File對象,它包含其他文件和文件夾
如果創建一個File對象並且它是一個目錄,那麽調用isDirectory()方法會返回true
可以用過調用該對象上的list()方法,來提取它包含的文件和文件夾的列表
下面展示的例子說明如何使用list()方法來檢查一個文件夾中包含的內容
import java.io.File; public class DirList { public static void main(String args[]) { String dirname = "/tmp"; File f1 = new File(dirname); if (f1.isDirectory()) { System.out.println( "目錄 " + dirname); String s[] = f1.list(); for (int i=0; i < s.length; i++) { File f = new File(dirname + "/" + s[i]); if (f.isDirectory()) { System.out.println(s[i] + " 是一個目錄"); } else { System.out.println(s[i] + " 是一個文件"); } } } else { System.out.println(dirname + " 不是一個目錄"); } } }
刪除目錄或文件
刪除文件可以使用java.io.File.delete()方法
以下代碼會刪除目錄/tmp/java/,即便目錄不為空
import java.io.File; public class DeleteFileDemo { public static void main(String args[]) { // 這裏修改為自己的測試目錄 File folder = new File("/tmp/java/"); deleteFolder(folder); } //刪除文件及目錄 public static void deleteFolder(File folder) { File[] files = folder.listFiles(); if(files!=null) { for(File f: files) { if(f.isDirectory()) { deleteFolder(f); } else { f.delete(); } } } folder.delete(); } }
Java Stream、File和IO