Java 輸入輸出流筆記
阿新 • • 發佈:2018-12-09
- 按流的方向
- 輸入流 InputStream Reader
- 輸出流 OutputStream Writer
- 按資料單元
- 位元組流 位元組流操作的資料單元是8 位的位元組 二進位制資料 InputStream OutputStream
- 字元流 字元流操作的資料單元是16位的字元 對字元效能方面提升 Reader Writer
- 按功能分類
- 節點流 最基本的檔案流 直接和底層檔案關聯
- 處理流 必須在節點流的基礎上建立|包裝 > 修飾器設計模式
-
流的基礎用法
- InputStream > FileInputStream
- 方法
- int read() 逐個位元組讀取 ,並返回讀取的內容(int單個位元組) IO的頻率最高
- int read( byte[] ) 一次讀取位元組到byte[]陣列中,並返回讀取的資料長度
-
//read() private void read1() { InputStream is = null; try { is = new FileInputStream(filePath); int c = 0; do { c = is.read(); System.out.print((char) c); } while (c != -1); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (is != null) { is.close(); } } catch (IOException e) { e.printStackTrace(); } } } //read(byte) private void read2() { InputStream is = null; try { is = new FileInputStream(filePath); byte[] b = new byte[1024]; int len = 0; do { len = is.read(b); for (int i = 0; i < len; i++) { System.out.print((char) b[i]); } } while (len != -1); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (is != null) { is.close(); } } catch (IOException e) { e.printStackTrace(); } } }
- 方法
- OutputStream > FileOutputStream
- 方法
- void write( int i ) 單個位元組寫入
- void write( byte[] ) 寫入一批位元組
-
/** * write(byte) write() * @param str 寫入內容 */ private void write1(String str) { OutputStream ops = null; try { ops = new FileOutputStream(filePath, true); // int ops.write((char) 65); // String ops.write(str.getBytes()); // String offset length ops.write(str.getBytes(), 0, str.length()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { ops.close(); } catch (IOException e) { e.printStackTrace(); } } }
- 方法
- Reader > FileReader
- 方法
- int read()
- int read( char[] )
-
private void read1() { Reader r = null; try { r = new FileReader(new File("iotest.txt")); char[] buffer = new char[1024]; StringBuffer sb = new StringBuffer(); while (true) { int len = r.read(buffer); if (len == -1) break; sb.append(buffer, 0, len); } System.out.println(sb.toString()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { r.close(); } catch (IOException e) { e.printStackTrace(); } } }
- 方法
- Writer > FileWriter
- 方法
- void write( int i )
- void write( String str )
-
private void write1() { Writer w = null; try { /* * FileWriter(File file, boolean append) * 引數append為true時,則續寫反之重寫 */ w = new FileWriter(new File("iotest.txt"), true); char[] cbuf = "\nbyteTest".toCharArray(); String str = "\nHelloWorld3.......\r\n你好世界"; // int w.write(65); // char[] w.write(cbuf); // char[] offset length w.write(cbuf, 0, cbuf.length); // String w.write(str); // String offset length w.write(str, 0, str.length()); // 清除快取 w.flush(); } catch (IOException e) { e.printStackTrace(); } finally { // close在呼叫時會呼叫flush try { w.close(); } catch (IOException e) { e.printStackTrace(); } } }
- 方法
-
綜合
private void copyText(String readFilePath,String writeFilePath) { Reader read = null; Writer write = null; try { read = new FileReader(new File(readFilePath)); write = new FileWriter(new File(writeFilePath)); char[] buffer = new char[1024]; int len = 0; while ((len = read.read(buffer)) != -1) { write.write(buffer, 0, len); write.flush(); } System.out.println("copy complete"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { read.close(); write.close(); } catch (IOException e) { e.printStackTrace(); } } } private void copyImage(String readFilePath,String writeFilePath) { InputStream in = null; OutputStream out = null; try { in = new FileInputStream(new File(readFilePath)); out = new FileOutputStream(new File(writeFilePath)); byte[] buffer = new byte[1024]; int len = 0; while ((len = in.read(buffer)) != -1) { out.write(buffer, 0, len); out.flush(); } System.out.println("copy complete"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { in.close(); out.close(); } catch (IOException e) { e.printStackTrace(); } } }
- InputStream > FileInputStream
-
緩衝流
- 特點
- 不能單獨建立,必須藉助節點流建立
- 類別
- BufferedInputStream > int read read( byte offset length ) 資料讀取到末尾時返回-1
- BufferedOutputStream > void write weite(byte offset length)
- 綜合
private void copyFile() { BufferedInputStream bis = null; BufferedOutputStream bos = null; try { bos = new BufferedOutputStream( new FileOutputStream("iotest2.txt")); bis = new BufferedInputStream( new FileInputStream("iotest.txt")); byte[] arr = new byte[1024]; int len = -1; while ((len = bis.read(arr)) != -1) { bos.write(arr, 0, len); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { bis.close(); bos.close(); } catch (IOException e) { e.printStackTrace(); } } }
- 綜合
- BufferedReader > readLine資料讀取到末尾時返回null
-
private void bufferRead() { BufferedReader br = null; try { FileReader r = new FileReader( new File("iotest.txt")); br = new BufferedReader(r); MyBufferedReader mb = new MyBufferedReader(r); String str = null; // while ((str = mb.myReadLine()) != null) { while ((str = br.readLine()) != null) { System.out.println(str); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } }
-
- BufferedWriter > 寫入後需要重新整理flush,關閉前會先重新整理
-
public void bufferWrite() { BufferedWriter bw = null; try { bw = new BufferedWriter( new FileWriter("iotest2.txt")); bw.write("bufferWrite重寫"); bw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } }
-
- 特點
-
轉換流
- 類別
- public class OutputStreamWriter extends > WriterOutputStreamWriter ( OutputStream out )
- public class InputStreamReader extends > ReaderInputStreamReader ( InputStream in )
-
//在控制檯輸入字元回車後,列印大寫字元 private void test1() throws IOException { InputStream is = System.in; OutputStream ou = System.out; BufferedReader br = new BufferedReader( new InputStreamReader(is)); BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(ou)); String line = null; while ((line = br.readLine()) != null) { if ("end".equals(line)) break; bw.write(line.toUpperCase()); bw.newLine(); bw.flush(); } br.close(); bw.close(); } //在控制檯輸入字元回車後,列印大寫字元在檔案中 private void test2() throws IOException { InputStream is = System.in; BufferedReader br = new BufferedReader( new InputStreamReader(is)); BufferedWriter bw = new BufferedWriter( new FileWriter("iotest.txt")); String line = null; while ((line = br.readLine()) != null) { if ("end".equals(line)) break; bw.write(line.toUpperCase()); //newLine()可跨平臺換行 bw.newLine(); bw.flush(); } br.close(); bw.close(); } //讀取檔案中字元,列印到控制檯中 private void test3() throws IOException { OutputStream ou = System.out; BufferedReader br = new BufferedReader( new FileReader("iotest.txt")); BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(ou)); String line = null; while ((line = br.readLine()) != null) { if ("end".equals(line)) break; bw.write(line.toUpperCase()); bw.newLine(); bw.flush(); } br.close(); bw.close(); } private void test4() throws IOException { InputStream is = System.in; OutputStream ou = System.out; BufferedInputStream bis = new BufferedInputStream(is); BufferedOutputStream bos = new BufferedOutputStream(ou); byte[] buffer = new byte[1024]; bis.read(buffer); bos.write(buffer); bos.close(); }
- 類別
-
列印流
- PrintWriter(OutputStream out, boolean autoFlush) autoFlush為true,自動重新整理
private void test1() throws IOException { InputStream is = System.in; PrintWriter out = new PrintWriter(System.out, true); BufferedReader br = new BufferedReader( new InputStreamReader(is)); String str = null; while ((str = br.readLine()) != null) { if ("end".equals(str)) break; out.println(str.toUpperCase()); } out.close(); br.close(); }
- PrintWriter(OutputStream out, boolean autoFlush) autoFlush為true,自動重新整理
-
記憶體流
- 特點
- io 的行為並不是對檔案進行操作,而是對記憶體中byte[]陣列進行操作
- byte[ ] 在程式中,是一個臨時存放資料的空間,並不是底層的資源,所以並不需要關閉流
- 類別
- ByteArrayInputStream(byte[] buf)
- ByteArrayOutputStream()
-
// 將bos讀取到的input中的內容,寫入bais中toString返回輸出 public String getTextByInputStream(InputStream input) { BufferedInputStream bos = null; ByteArrayOutputStream bais = null; try { bos = new BufferedInputStream(input); bais = new ByteArrayOutputStream(); int len = -1; while ((len = bos.read()) != -1) { bais.write(len); } } catch (IOException e) { e.printStackTrace(); } finally { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } return bais.toString(); } private void test1() { BufferedInputStream bis = null; BufferedOutputStream bos = null; try { // 將圖片檔案讀取,存入到記憶體流中 bis = new BufferedInputStream( new FileInputStream("image.png")); bos = new BufferedOutputStream( new FileOutputStream("copyimage.png")); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int i = -1; // while ((i = bis.read()) != -1) { // baos.write(i); // } while ((i = bis.read(buffer)) != -1) { baos.write(buffer, 0, i); } System.out.println("完成存入記憶體操作"); // 將記憶體流中的圖片讀取,寫入到檔案中 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); int j = -1; while ((j = bais.read()) != -1) { bos.write(j); } System.out.println("完成磁碟寫入操作"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { bis.close(); bos.close(); } catch (IOException e) { e.printStackTrace(); } } }
- 特點
-
物件流
- 序列化:把物件狀態(內部資料等)儲存到某種介質中,該介質可以是檔案、網路等
- 反序列化:從介質中根據所儲存的物件狀態資訊,重構物件
- 類別
- ObjectInputStream(InputStream in) 將物件儲存到二進位制檔案中序列化(序列化)
- ObjectOutputStream (OutputStream out) 在二進位制檔案中查詢物件進行反序列化(並行化)
-
private void readObject() { ObjectInputStream ois = null; try { ois = new ObjectInputStream( new FileInputStream("iotest2.bin")); Person person = (Person) ois.readObject(); System.out.println("——重構物件完成——"); System.out.println(person); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } private void writeTo(Person person) { ObjectOutputStream oos = null; try { oos = new ObjectOutputStream( new FileOutputStream("iotest2.bin")); oos.writeObject(person); System.out.println("——寫入物件完成——"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } } //只有支援java.io.Serializable介面的物件才能寫入流中 //只能從流中讀取支援java.io.Serializable或 java.io.Externalizable介面的物件 public class Person implements Serializable { private static final long serialVersionUID = 1293810121342278585L; private String name; private String sex; public Person(String name, String sex) { super(); this.name = name; this.sex = sex; } //省略toString() }
-
資料流
- 特點:提供了各種資料型別對應的讀取和寫入的方式
- 類別
- DataInputStream (InputStream in)
- DataOutputStream (OutputStream out)
-
public static void main(String[] args) { DataOutputStream dataOutput = null; DataInputStream dataInput = null; try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); dataOutput = new DataOutputStream(baos); dataOutput.writeBoolean(true); dataOutput.writeUTF("string"); dataOutput.writeInt(1024); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); dataInput = new DataInputStream(bais); System.out.println( dataInput.readBoolean() + ":" + dataInput.readUTF() + ":" + dataInput.readInt()); } catch (IOException e) { e.printStackTrace(); } finally { try { dataOutput.close(); dataInput.close(); } catch (IOException e) { e.printStackTrace(); } } }
-
序列流
- 類別
- SequenceInputStream (InputStream s1, InputStream s2) 合併兩個輸入位元組流
- SequenceInputStream (Enumeration<? extends InputStream> e) 合併多個個輸入位元組流
-
/** * 合併多個檔案 */ private void test2() { FileInputStream fis1 = null; FileInputStream fis2 = null; FileInputStream fis3 = null; FileOutputStream fos = null; SequenceInputStream sis = null; try { fis1 = new FileInputStream(new File("iotest.txt")); fis2 = new FileInputStream(new File("iotest2.txt")); fis3 = new FileInputStream(new File("iotest3.txt")); fos = new FileOutputStream(new File("iotest1.txt")); Vector<InputStream> v = new Vector<>(); v.add(fis1); v.add(fis2); v.add(fis3); Enumeration<InputStream> enumeration = v.elements(); sis = new SequenceInputStream(enumeration); byte[] buffer = new byte[1024]; int len = -1; while ((len = sis.read(buffer)) != -1) { fos.write(buffer, 0, len); } System.out.println("——合併完成——"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { fis1.close(); fis2.close(); fis3.close(); fos.close(); sis.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 合併兩個檔案 */ private void test1() { SequenceInputStream sis = null; FileOutputStream fos = null; InputStream f1 = null; InputStream f2 = null; try { f1 = new FileInputStream("iotest.txt"); f2 = new FileInputStream("iotest2.txt"); fos = new FileOutputStream("iotest3.txt"); sis = new SequenceInputStream(f1, f2); int len = -1; byte[] buffer = new byte[1024]; while ((len = sis.read(buffer)) != -1) { fos.write(buffer, 0, len); } System.out.println("————合併完成————"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { f1.close(); f2.close(); sis.close(); fos.close(); } catch (IOException e) { e.printStackTrace(); } } }
- 類別
-
RandomAccessFile
- 特點:RandomAccessFile(任意訪問檔案)實現 DataOutput和 DataInput 具備對檔案讀取和寫入的功能
- 方法
- void seek(long pos) 設定檔案指標偏移,從該檔案的開頭測量,發生下一次讀取或寫入
- long getFilePointer() 返回此檔案中的當前偏移量
-
//寫入物件 private void test2() throws IOException { RandomAccessFile ra = new RandomAccessFile("002.bin", "rw"); Person person1 = new Person("make", "male"); Person person2 = new Person("mary", "female"); person1.writeToFile(ra); person2.writeToFile(ra); for (int i = 0; i < ra.length(); i = (int) ra.getFilePointer()){ ra.seek(i); System.out.println(ra.readUTF() + "," + ra.readUTF()); } ra.close(); } //寫入字串 private void test1() throws IOException { /** * r 以只讀的方式開啟檔案 * rw 以讀、寫的方式開啟檔案,如果不存在嘗試建立 * rwd 相對rw模式,還要求對檔案<內容>的每個更新都同步寫入到底層儲存裝置中 * rws 相對rw模式,還要求對檔案的<內容或元資料>的每個更新都同步寫入到底層儲存裝置中 */ RandomAccessFile raf = new RandomAccessFile("001.txt", "rw"); System.out.println(raf.getFilePointer()); raf.writeUTF("helloworld"); System.out.println(raf.getFilePointer()); raf.writeUTF("你好世界HelloWorld"); System.out.println("寫入完成"); // raf.seek(0); // System.out.println(raf.readUTF()); // raf.seek(12); // System.out.println(raf.readInt()); for (int i = 0; i < raf.length();i = (int) raf.getFilePointer()){ raf.seek(i); System.out.println(raf.readUTF()); } raf.close(); } public class Person implements Serializable { private static final long serialVersionUID = 1293810121342278585L; private String name; private String sex; public Person(String name, String sex) { super(); this.name = name; this.sex = sex; } public void writeToFile(RandomAccessFile ra) { try { ra.writeUTF(this.name); ra.writeUTF(this.sex); } catch (IOException e) { e.printStackTrace(); } } @Override public String toString() { return "Person [name=" + name + ", sex=" + sex + "]"; } }