1. IO流理解 IO流中的I是單詞Input的縮寫,表示輸入或者讀(Read),O是單詞Output的縮寫,表示輸出或寫(Write),輸入輸出或者讀寫都是相對於記憶體而言的,輸入即從硬碟中讀取數據到記憶體中,輸出即將記憶體中的數據寫入到硬碟。IO流就是輸入和輸出時的數據流(記憶體和硬碟之間的管道),IO ...
1. IO流理解
IO流中的I是單詞Input的縮寫,表示輸入或者讀(Read),O是單詞Output的縮寫,表示輸出或寫(Write),輸入輸出或者讀寫都是相對於記憶體而言的,輸入即從硬碟中讀取數據到記憶體中,輸出即將記憶體中的數據寫入到硬碟。IO流就是輸入和輸出時的數據流(記憶體和硬碟之間的管道),IO的輸入或輸出也可以看做是文件的讀和寫,因為硬碟中的數據其實都是以文件的形式存儲的,在硬碟上對文件的讀寫操作就對應了記憶體中對數據的輸入和輸出操作。
2. 流的讀取方式
3. File類
“java.io.File”類和文件流的操作沒有關係,也就是不能對文件進行讀和寫,File類是文件和目錄路徑名的一種抽象表示形式,即一個文件是File對象,一個目錄也是File對象,它的構造方法中只需要傳入一個文件或目錄的路徑名即可,註意,對於路徑分隔符,Windows和Linux使用的分別是“\”和“/”,但是File中傳入的路徑可以統一使用“/”,在Windows中也可以識別。
File中的常用方法:
-
-
boolean createNewFile():如果File對象不存在,則將File對象創建為一個新的文件,如果存在則不能創建。
-
boolean mkdir():如果File對象不存在,則將File對象創建為一個新的目錄。註意,此方法只能創建單個目錄,不能遞歸創建目錄。
-
boolean mkdirs():如果File對象不存在,則將File對象以遞歸方式創建目錄。
-
String getParent():獲取File對象的父路徑(上一級路徑)。
-
File getParentFile():返回File對象的父路徑的File對象。
-
String getAbsolutePath():返回File對象的絕對路徑。
-
boolean delete():刪除File對象表示的文件或目錄。
-
String getName():獲取File對象的文件名或目錄名。
-
boolean isFile():判斷File對象是否是一個文件。
-
boolean isDirectory():判斷File對象是否是一個目錄。
-
long lastModified():返回File對象最後一次修改的時間的總毫秒數(從1970年1月1日開始)。
-
long length():返回File對象的總位元組數。
-
boolean renameTo(File dest):File對象重命名。
-
4. Java中的IO流
使用示例:
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class FileInputStreamTest { public static void main(String[] args) { FileInputStream fis = null; try{ // FileInputStream中拋出了一個FileNotFoundException異常,即編譯時異常 // 需要程式員手動處理,這裡加一個try進行捕獲 // input.txt文件中只有一行數據:helloworld fis = new FileInputStream("Z:\\Study\\Java\\input.txt"); /* // 以下read()只是演示,實際並不常用 // 列印結果為: // 104 // 101 // 108 // 108 // 111 // 119 // 111 // 114 // 108 // 100 int byteData = 0; while ((byteData = fis.read()) != -1) { System.out.println(byteData); } */ // 以下使用read(byte[] b)方法讀取文件內容 byte[] bytes = new byte[6]; int count = fis.read(bytes); System.out.println(count); // 6 System.out.println(new String(bytes)); // hellow System.out.println(new String(bytes, 0, count)); // hellow count = fis.read(bytes); System.out.println(count); // 4 System.out.println(new String(bytes)); // orldow System.out.println(new String(bytes, 0, count)); // orld count = fis.read(bytes); System.out.println(count); // -1 System.out.println(new String(bytes)); // orldow } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fis != null) { try { // close方法也是拋出了一個IOException異常的編譯時異常,同樣加一個try進行捕獲 fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
FileOutpuStream
將位元組內容寫入到文件中,構造方法中同樣可以傳入一個文件路徑或者表示文件的File對象,同時還可以指定第二參數為true。當只傳入一個文件路徑或File對象,如果文件已存在,會清空文件內容,如果文件不存在,則會自動創建該文件;也可以指定第二個參數為true,表示如果文件已存在則不會清空文件,而是會往文件末尾追加數據。常用的方法有:
使用示例:
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStreamTest { public static void main(String[] args) { FileOutputStream fos = null; try { // 只傳入一個文件路徑:如果文件已存在,會清空文件內容,如果文件不存在,則會自動創建該文件 // fos = new FileOutputStream("Z:\\Study\\Java\\output.txt"); // 第二個參數表示如果文件已存在則不會清空文件,而是會往文件末尾追加數據 fos = new FileOutputStream("Z:\\Study\\Java\\output.txt", true); byte[] bytes = {97, 98, 99, 100}; // 將bytes數組全部寫到文件中 fos.write(bytes); // 將bytes數組的一部分寫到文件中 fos.write(bytes, 0, 2); // 將字元串輸出到文件中 String s = "你好,世界"; byte[] bs = s.getBytes(); fos.write(bs); // 文件輸出完成後,一定記得刷新一下 fos.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null) { try { // 文件操作完成後一定記得調用close()方法 fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
FileReader:和FileInputStream相比,在使用上都是類似的,只是需要把byte數組換成char數組即可。
FileWriter:和FileOutpuStream相比,在使用上也都是類似的,只是要把byte數組換成char數組,另外,由於字元串的特殊性,FileWriter的write方法還可以直接寫入一個字元串到文件。
6. 緩衝流
緩衝流表示帶有緩衝區的位元組流或字元流,特點是使用這些流的時候不需要自定義byte數組或char數組。
包裝流和節點流:緩衝流的使用涉及到一些概念,當一個流的構造方法中需要另一個流的時候,被傳入的這個流稱為節點流,外部負責包裝這個節點流的流稱為包裝流或處理流。關閉包裝流的時候也是只需要調用最外層包裝流的close()方法即可,裡面的節點流會自動關閉。同樣,對於輸出的流,也是只需要調用最外層包裝流的flush()方法即可。
BufferedInputStream:是一個包裝流,構造方法中需要傳入一個InputStream類型(位元組類型)的節點流。
BufferedOutputStream:是一個包裝流,構造方法中需要傳入一個OutputStream類型(位元組類型)的節點流。
import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class BufferedReaderTest { public static void main(String[] args) { BufferedReader br = null; try { // 這裡reader就是一個節點流,br就是一個包裝流或處理流 // 文件內容只有一行:helloworld FileReader reader = new FileReader("Z:\\Study\\Java\\input.txt"); br = new BufferedReader(reader); // 讀取一行數據,註意返回的數據是不包含末尾的換行符的 String line = br.readLine(); System.out.println(line); // helloworld // 讀取到文件末尾,返回null line = br.readLine(); System.out.println(line); // null } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 對於包裝流來說,只需要調用最外層包裝流的close()方法即可,裡面的節點流會自動關閉。 if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
PrintStream out = new PrintStream(new FileOutputStreasm("log.txt", true)); System.setOut(out);
// 實現Serializable,但這個介面沒有任何方法需要去重寫 public class User implements Serializable { private int id; private String name; ... }
序列化單個java對象
User u = new User(123, "zhangsan"); // 將user對象序列化到Z:\\userinfo文件中 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Z:\\userinfo")); oos.writeObject(s); oos.flush(); oos.close();
序列化多個java對象
// 這裡使用ArrayList存放多個User對象 List<User> userList = new ArrayList<>(); userList.add(new User(111, "zhangyi")); userList.add(new User(222, "zhanger")); userList.add(new User(333, "zhangsan")); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Z:\\userinfo")); oos.writeObject(userList); oos.flush(); oos.close();
反序列化java對象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Z:\\userinfo")); // 反序列化出來的對象需要進行強制類型轉換一下 List<User> userList = (List<User>)ois.readObject(); ois.close();
username=root
password=123456
FileReader reader = new FileReader("user-conf.txt"); Properties pro = new Properties(); pro.load(reader); String username = pro.getProperty("username"); System.out.println(username); // root