常見IO流彙總——已完結

1 IO

1.1 IO的分類

根據數據流向分類

  • 輸入流:把數據從其他設備讀取到內存

​ 以InputStream,Reader結尾

  • 輸出流:把數據從內存中寫出到其他設備

​ 以OutputStream、Writer結尾

根據數據類型分類

  • 字節流:已字節爲單位,讀寫數據

​ 以InputStream和OutputStream結尾

  • 字符流:以字符爲單位,讀寫數據

​ 以Reader和Writer結尾

根據IO流的角色不同

  • 節點流:可以從或向一個特定的地方(節點)讀寫數據

  • 處理流:是對一個已經存在的流進行連接和封裝,通過所封裝的流的功能調用實現數據讀寫

常用的節點流

  • 文 件 FileInputStream FileOutputStrean FileReader FileWriter 文件進行處理的節點流。
  • 字符串 StringReader StringWriter 對字符串進行處理的節點流。
  • 數 組 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter 對數組進行處理的節點流(對應的不再是文件,而是內存中的一個數組)。
  • 管 道 PipedInputStream、PipedOutputStream、PipedReader、PipedWriter對管道進行處理的節點流。

常用處理流

  • 緩衝流:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter—增加緩衝功能,避免頻繁讀寫硬盤。
  • 轉換流:InputStreamReader、OutputStreamReader—實現字節流和字符流之間的轉換。
  • 對象流:ObjectInputStream、ObjectOutputStream–提供直接讀寫Java對象功能

1.2 字節輸入流【InputStream】

1.2.1 FileInputStream類

java.io.FileInputStream 類是文件輸入流,從文件中讀取字節

  • 構造方法

    FileInputStream(File file) : 通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的 File對象 file命名。

    FileInputStream(String name) : 通過打開與實際文件的連接來創建一個 FileInputStream ,該文件由文件系統中的路徑名 name命名。

  • 構造代碼示例

    File file = new File("c:/aa/a.txt");
    FileInputStream in1 = new FileInputStream(file);       //File類型參數
    FileInputStream in2 = new FileInputStream("c:/aa/a.txt");   //String參數
    

1.2.2 讀取字節數據

讀取字節

  • read()方法,每次可以讀取一個字節的數據,提升爲int類型,讀取到文件末尾,返回-1

  • 示例代碼(循環讀取)

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    
    import javax.imageio.stream.FileImageInputStream;
    
    public class Test7 {
    	public static void main(String[] args) {
    		File file = new File("c:/aa/a.txt");
    		FileInputStream in1 = null;
    		try {  
    			 in1 = new FileInputStream(file);       //File類型參數
    //			FileInputStream in2 = new FileInputStream("c:/aa/a.txt");   //String參數
    			int b;
    			while((b = in1.read()) != -1){
    				System.out.println((char)b);
    			}
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}finally{
    			try {
    				in1.close();
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
    }
    
  • 使用字節數組讀取:read(byte[] b),每次讀取b的長度個字節到數組中,返回讀取到的有效字節個數,讀取到末尾時,返回-1 ,代碼使用演示:

    循環讀取

    public class Test6 {
    	public static void main(String[] args) {
    		FileInputStream in = null;
    		FileOutputStream out = null;
    		try {
    			in = new FileInputStream("c:/aaa/java.txt");
    			byte b[] = new byte[5];
    			int len = 0;
    			while((len = in.read(b)) != -1){
    					System.out.println(new String(b,0,len));
    			}
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}finally{
    			try {
    				in.close();
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
    }
    
    

1.3 字節輸出流【OutputStream】

java.io.OutputStream 抽象類是表示字節輸出流的所有類的超類,將指定的字節信息寫出到目的地。它定義了字節輸出流的基本共性功能方法。

  • public void close() :關閉此輸出流並釋放與此流相關聯的任何系統資源。
  • public void flush() :刷新此輸出流並強制任何緩衝的輸出字節被寫出。
  • public void write(byte[] b):將 b.length字節從指定的字節數組寫入此輸出流。
  • public void write(byte[] b, int off, int len) :從指定的字節數組寫入 len字節,從偏移量 off開始輸出到此輸出流。
  • public abstract void write(int b) :將指定的字節輸出流。

1.3.1 FileOutputStream類

  • 構造方法

    • public FileOutputStream(File file):創建文件輸出流以寫入由指定的 File對象表示的文件。

    • public FileOutputStream(String name): 創建文件輸出流以指定的名稱寫入文件。

      示例代碼

      public class FileOutputStreamConstructor throws IOException {
          public static void main(String[] args) {
         	 	// 使用File對象創建流對象
              File file = new File("a.txt");
              FileOutputStream fos = new FileOutputStream(file);
            
              // 使用文件名稱創建流對象
              FileOutputStream fos = new FileOutputStream("b.txt");
          }
      }
      
  • 寫出字節數據

    write(int b) 方法,每次可以寫出一個字節數據

    write(byte[] b)方法,每次可以寫出數組中的數據

    示例代碼:

     FileOutputStream fos = new FileOutputStream("c:/aaa/text.txt");     
          	// 字符串轉換爲字節數組
          	byte[] b = {97,98,99,100,101};
          	// 寫出字節數組數據
          	fos.write(b);
          	// 關閉資源
            fos.close();
    

    寫出指定長度字節數組:write(byte[] b, int off, int len) ,每次寫出從off索引開始,len個字節

    示例代碼:

     FileOutputStream fos = new FileOutputStream("c:/aaa/text.txt");     
          	// 字符串轉換爲字節數組
          	byte[] b = "abcde".getBytes();
    		// 寫出從索引2開始,2個字節。索引2是c,兩個字節,也就是cd。
            fos.write(b,2,2);
          	// 關閉資源
            fos.close();
    

1.3.2 方法運用

例如將”c:/aaa/java.txt“拷貝到”c:/bbb/java1.txt“

示例代碼

public class Test {
	public static void main(String[] args) {
		FileInputStream in = null;
		FileOutputStream out = null;
		try {
			in = new FileInputStream("c:/aaa/java.txt");
			 out  = new FileOutputStream("c:/bbb/java1.txt");
			byte b[] = new byte[5];
			int len = 0;
			while((len = in.read(b)) != -1){
				out.write(b, 0, len);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				in.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

1.4 字符輸入流【Reader】

1.4.1 常用方法

  • public void close() :關閉此流並釋放與此流相關聯的任何系統資源
  • public int read() : 從輸入流讀取一個字符
  • public int read(char[] cbuf) : 從輸入流中讀取一些字符,並將它們存儲到字符數組 cbuf中

1.4.2 FileReader類

構造方法

  • FileReader(File file) : 創建一個新的 FileReader ,給定要讀取的File對象

  • FileReader(String fileName) : 創建一個新的 FileReader ,給定要讀取的文件的名稱

  • 示例代碼

FileReader in = new FileReader("c:/aa/bb/java.txt"); //使用了第二種構造器

讀取字符

  • 核心代碼
int i = 0;               //read()方法
while((i = in.read()) != -1){
    System.out.print((char)i);
}
in.close;

//第二種方法 使用數組讀取
int len = 0;
char[] b = new char[1024];
while((len = in.read(b)) != -1){
    System.out.print(new String(b,0,len));
}
in.close;

1.5 字符輸出流【Writer】

1.5.1 常用方法

  • void write(int c) 寫入單個字符。
  • void write(char[] cbuf)寫入字符數組。
  • abstract void write(char[] cbuf, int off, int len)寫入字符數組的某一部分,off數組的開始索引,len寫的字符個數。
  • void write(String str)寫入字符串。
  • void write(String str, int off, int len) 寫入字符串的某一部分,off字符串的開始索引,len寫的字符個數。
  • void flush()刷新該流的緩衝。
  • void close() 關閉此流,但要先刷新它。

1.5.2 FileWriter類

構造方法

  • FileWriter(File file) : 創建一個新的 FileWriter,給定要讀取的File對象。

  • FileWriter(String fileName): 創建一個新的 FileWriter,給定要讀取的文件的名稱。

  • 示例代碼

    FileWriter fw = new FileWriter("c:/aa/bb/java.txt"); //使用第二種構造方法
    

寫出數據

  • write(int value)方法

    fw.write(97);  //write(int value)方法
    
  • flush()與close()方法

    因爲內置緩衝區的原因,如果不關閉輸出流,無法寫出字符到文件中。但是關閉的流對象,是無法繼續寫出數據的。如果我們既想寫出數據,又想繼續使用流,就需要flush 方法了

    • flush :刷新緩衝區,流對象可以繼續使用。
    • close :先刷新緩衝區,然後通知系統釋放資源。流對象不可以再被使用了。
  • write(char[] cbuf)write(char[] cbuf, int off, int len)方法

    char[] a = {'你','好','啊'};
    fw.write(a);
    fw.write(a,1,2)  // 寫出從索引1開始,2個字節。索引1是'好',兩個字節,也就是'好啊'
    
  • write(String str) 和 write(String str, int off, int len)方法

    String name = "湯小強";
    fw.write(name);
    fw.write(name,1,2); //結果"小強"
    

1.6 緩衝流

1.6.1 字節緩衝流

構造方法

  • public BufferedInputStream(InputStream in) :創建一個 新的緩衝輸入流。

  • public BufferedOutputStream(OutputStream out): 創建一個新的緩衝輸出流。

  • 示例代碼

    BufferedInputStream bis = new BuffBufferedInputStream(new FileInputStream("c:/aa/bb/java.txt"));
    
    BufferedOutputStream bos = new BuffBufferedOutputStream(new FileOutputStream("c:/aa/bb/java.txt"));
    
  • 優點:效率高

1.6.2 字符緩衝流

構造方法

  • public BufferedReader(Reader in) :創建一個 新的緩衝輸入流。

  • public BufferedWriter(Writer out): 創建一個新的緩衝輸出流。

  • 示例代碼

    BufferedReader br = new BufferedReader(new FileReader("c:/aa/bb/java.txt"));
    
    
    BufferedWriter bw = new BufferedWriter(new FileWriter("c:/aa/bb/java.txt"));
    

特有方法

  • BufferedReader:public String readLine(): 讀一行文字。

  • BufferedWriter:public void newLine(): 寫一行行分隔符,由系統屬性定義符號。

  • 示例代碼

    String line  = null;
          	// 循環讀取,讀取到最後返回null
            while ((line = br.readLine())!=null) {
                System.out.print(line);
                System.out.println("------");
            }
            
    //newLine()
    	 	bw.write("湯");
          	// 寫出換行
            bw.newLine();
            bw.write("小");
            bw.newLine();
    

1.7 轉換流

1.7.1 InputStreamReader類

構造方法

  • InputStreamReader(InputStream in) : 創建一個使用默認字符集的字符流。

  • InputStreamReader(InputStream in, String charsetName): 創建一個指定字符集的字符流

  • 舉例代碼

    InputStreamReader isr = new InputStreamReader(new FileInputStream("c:/aa/bb/java.txt"));
    
    //下面指定了程序的讀取文件類型
    InputStreamReader isr2 = new InputStreamReader(new FileInputStream("c:/aa/bb/java_GBK.txt") , "GBK");//可以讀取GBK文件,即使程序本身不是GBK
    

指定編碼讀取

while ((read = isr2.read()) != -1) {
            System.out.print((char)read);// 
        }
        isr2.close();

1.7.2 OutputStreamWriter類

構造方法

  • OutputStreamWriter(OutputStream in) : 創建一個使用默認字符集的字符流。

  • OutputStreamWriter(OutputStream in, String charsetName): 創建一個指定字符集的字符流。

  • 示例代碼

    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c:/aa/bb/java.txt"));
    
    //指定程序寫出的編碼
    OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("c:/aa/bb/java.txt"), "GBK");
    

指定編碼寫出

//文件保存編碼爲GBK
OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("c:/aa/bb/java.txt") , "GBK");
osw2.write("你好");

案例

public class Test {
	//將gbk格式的文件轉換爲utf-8格式存儲
	public static void main(String[] args) {
		Reader in = null;
		Writer out = null;
		try {
			
			in = new InputStreamReader(
					new FileInputStream("c:/aa/bb/java_gbk.txt"), "gbk");
			out = new OutputStreamWriter(
					new FileOutputStream("c:/aa/bb/java_gbk.txt"), "utf-8");
			int i = 0;
			while((i = in.read()) != -1){
				out.write(i);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			try {
				in.close();
				out.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
}

1.8 序列化

1.8.1 ObjectOutputStream類

java.io.ObjectOutputStream 類,將Java對象的原始數據類型寫出到文件,實現對象的持久存儲。

構造方法

  • public ObjectOutputStream(OutputStream out) : 創建一個指定OutputStream的ObjectOutputStream

  • 示例代碼

    ObjectOutputStream out = new ObjectOutputStream(new FileoutputStream("c:/aa/bb/java.txt"));
    

序列化注意事項

  • 該類必須實現java.io.Serializable 接口
  • 該類的所有屬性必須是可序列化的
  • 靜態變量的值不會序列化

1.8.2 ObjectInputStream類

ObjectInputStream反序列化流,將之前使用ObjectOutputStream序列化的原始數據恢復爲對象

構造方法

public ObjectInputStream(InputStream in) : 創建一個指定InputStream的ObjectInputStream。

1.8.3 案例演示

代碼示例

public class Test {
	public static void main(String[] args) {
		/*
		 * 聲明一個Message類
		 * 包含:發送者(sender)、接收者(recipient)、消息內容(content)、發送時間(time)
		 * 創建一個Message對象,並寫到message.dat文件中,並再次讀取顯示
		 */
		
		Message message = new Message("tom", "jack", "請儘快回覆", "2020年05月28號晚 20:00");
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(new FileOutputStream("c:/aa/bb/message.dat"));
			ObjectInputStream ois=new ObjectInputStream(
					new FileInputStream("c:/aa/bb/message.dat"));
			oos.writeObject(message);
			Object object = ois.readObject();
			System.out.println(object);
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			try {
				oos.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
	}
}


class Message implements Serializable{
	private String sender;
	private String recipient;
	private String content;
	private String time;
	public Message(String sender, String recipient, String content, String time) {
		super();
		this.sender = sender;
		this.recipient = recipient;
		this.content = content;
		this.time = time;
	}
	public String getSender() {
		return sender;
	}
	public void setSender(String sender) {
		this.sender = sender;
	}
	public String getRecipient() {
		return recipient;
	}
	public void setRecipient(String recipient) {
		this.recipient = recipient;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getTime() {
		return time;
	}
	public void setTime(String time) {
		this.time = time;
	}
	@Override
	public String toString() {
		return "Message [sender=" + sender + ", recipient=" + recipient + ", content=" + content + ", time=" + time
				+ "]";
	}
	
	
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章