1. 程式人生 > >Java 輸入輸出流筆記

Java 輸入輸出流筆記

  • 流的分類
    1. 按流的方向
      1. 輸入流     InputStream Reader
      2. 輸出流     OutputStream Writer
    2. 按資料單元
      1. 位元組流     位元組流操作的資料單元是8 位的位元組    二進位制資料    InputStream OutputStream 
      2. 字元流     字元流操作的資料單元是16位的字元   對字元效能方面提升    Reader Writer 
    3. 按功能分類
      1. 節點流     最基本的檔案流 直接和底層檔案關聯
      2. 處理流     必須在節點流的基礎上建立|包裝  >  修飾器設計模式
    4. 流的基礎用法

      1. InputStream > FileInputStream
        1. 方法
          1. int read()            逐個位元組讀取 ,並返回讀取的內容(int單個位元組) IO的頻率最高
          2. int read( byte[] )  一次讀取位元組到byte[]陣列中,並返回讀取的資料長度
        2. 	//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();
          			}
          		}
          	}
      2. OutputStream > FileOutputStream
        1. 方法
          1. void write( int i )     單個位元組寫入
          2. void write( byte[] )  寫入一批位元組
        2. 
          	/**
          	 * 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();
          			}
          		}
          	}
      3. Reader > FileReader
        1. 方法
          1. int read()
          2. int read( char[] )
        2. 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();
          			}
          		}
          	}
      4. Writer > FileWriter
        1. 方法
          1. void write( int i )
          2. void write( String str )
        2. 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();
          			}
          		}
          	}
      5. 綜合

        	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();
        			}
        		}
        	}
    5. 緩衝流

      1. 特點
        1. 不能單獨建立,必須藉助節點流建立
      2. 類別
        1. BufferedInputStream       > int read read( byte offset length ) 資料讀取到末尾時返回-1
        2. BufferedOutputStream    > void write weite(byte offset length)
          1. 綜合
                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();
            	    }
                }
            }
        3. BufferedReader  > readLine資料讀取到末尾時返回null
          1. 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();
            		}
            	}
            }
        4. BufferedWriter  > 寫入後需要重新整理flush,關閉前會先重新整理
          1. 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();
            		}
            	}
            }
    6. 轉換流

      1. 類別
        1. public class OutputStreamWriter extends > WriterOutputStreamWriter ( OutputStream out ) 
        2. public class InputStreamReader extends >  ReaderInputStreamReader ( InputStream in ) 
      2.         //在控制檯輸入字元回車後,列印大寫字元
                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();
                }
    7. 列印流

      1. 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();
        	}
    8. 記憶體流

      1. 特點
        1. io 的行為並不是對檔案進行操作,而是對記憶體中byte[]陣列進行操作
        2. byte[ ] 在程式中,是一個臨時存放資料的空間,並不是底層的資源,所以並不需要關閉流
      2. 類別
        1. ByteArrayInputStream(byte[] buf) 
        2. ByteArrayOutputStream() 
      3. 	// 將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();
        			}
        		}
        	}
    9. 物件流

      1. 序列化:把物件狀態(內部資料等)儲存到某種介質中,該介質可以是檔案、網路等
      2. 反序列化:從介質中根據所儲存的物件狀態資訊,重構物件
      3. 類別
        1. ObjectInputStream(InputStream in) 將物件儲存到二進位制檔案中序列化(序列化)
        2. ObjectOutputStream (OutputStream out)  在二進位制檔案中查詢物件進行反序列化(並行化)
      4.         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()
                }
    10. 資料流

      1. 特點:提供了各種資料型別對應的讀取和寫入的方式
      2. 類別
        1. DataInputStream (InputStream in)
        2. DataOutputStream (OutputStream out)
      3.     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();
        			}
        		}
        	}
    11. 序列流

      1. 類別
        1. SequenceInputStream (InputStream s1, InputStream s2)  合併兩個輸入位元組流
        2. SequenceInputStream (Enumeration<? extends InputStream> e)  合併多個個輸入位元組流
      2.     
                /**
        	 * 合併多個檔案
        	 */
        	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();
        			}
        		}
        	}
    12. RandomAccessFile

      1. 特點:RandomAccessFile(任意訪問檔案)實現 DataOutput和 DataInput 具備對檔案讀取和寫入的功能
      2. 方法
        1. void seek(long pos)  設定檔案指標偏移,從該檔案的開頭測量,發生下一次讀取或寫入
        2. long getFilePointer()  返回此檔案中的當前偏移量
      3.         //寫入物件	
                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 + "]";
                	}
                }