2020/12/05 java作業十

巴拉拉小摩托發表於2020-12-06

1.

1)從流動方向上看,一般分為輸入流和輸出流兩類。

2)從讀取型別上看,一般分為位元組流和字元流。

3)從發生的源頭上看,一般分為節點流和過濾流。

2.位元組流                                                                              字元流

java.io.inputstream                                                               java.io.reader

  java.io.fileinputstream                                                      java.io.filereader

  java.io.pipedinputstream                                                  java.io.pipedreader

  java.io.bufferedinputstream                                                 java.io.bufferedreader

java.io.outputstream                                                            java.io.writer

java.io.fileoutputstream                                                        java.io.filewriter

java.io.pipedoutputstream                                                    java.io.pipedwriter

       java.io.bufferedoutputstream                                                 java.io.bufferedwriter

1)FileInputStream的作用在於通過指定檔案路徑的方式,將一個檔案中的內容作為其他流的資料來源,從而可使用流的方式對檔案進行讀操作;FileOutputstream的作用在於通過指定檔案路徑的方式,將一個檔案作為其他流的輸出目的地,從而可使用流的方式對檔案進行寫操作。

fileinputstream舉例

import java.io.*;
public class OpenFile 
{
    public static void main(String args[]) throws IOException
    {
        try
        {                                          //建立檔案輸入流物件
            FileInputStream  rf = new FileInputStream("OpenFile.java");
            int n=512,c=0;
            byte buffer[] = new byte[n];
            while ((c=rf.read(buffer,0,n))!=-1 )   //讀取輸入流
            {
                System.out.print(new String(buffer,0,c));				
            }            
            rf.close();                            //關閉輸入流
        }
        catch (IOException ioe)
        { System.out.println(ioe);}
        catch (Exception e)
        { System.out.println(e);}
    }
}
fileoutputstream舉例
import java.io.*;
public class Write1 
{
    public static void main(String args[])
    {
        try
        {   System.out.print("Input: ");
            int count,n=512;
            byte buffer[] = new byte[n];
            count = System.in.read(buffer);        //讀取標準輸入流
            FileOutputStream  wf = new FileOutputStream("Write1.txt");
                                                   //建立檔案輸出流物件
            wf.write(buffer,0,count);              //寫入輸出流
            wf.close();                            //關閉輸出流
            System.out.println("Save to Write1.txt!");
        }
        catch (IOException ioe)
        { System.out.println(ioe);}
        catch (Exception e)
        { System.out.println(e);}
    }
}

2)管道用來把一個程式、執行緒和程式碼塊的輸出連線到另一個程式、執行緒和程式碼塊的輸入。管道輸入流作為一個通訊管道的接收端,管道輸出流則作為傳送端。管道流必須輸入/輸出並用,即在使用管道前,兩者必須進行連線。

pipedinputstream和pipedoutputstream舉例
package pipedIO;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.Date;
public class PipedIO {
	private PipedInputStream pis = new PipedInputStream();
	private PipedOutputStream pos = new PipedOutputStream();

	public static void main(String[] args) throws IOException {
		PipedIO pipedIO = new PipedIO();
		pipedIO.initThread();
	}

	private void initThread() throws IOException {
		pos.connect(pis);
		Thread input = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					while (true) {
						String time = new Date().toString();
						pos.write(time.getBytes());
						System.out.println("輸出流完成一次資料寫出,資料為"+time);
						Thread.sleep(1000);
					}
				} catch (IOException | InterruptedException e) {
					e.printStackTrace();
				}
			}
		});

		Thread output = new Thread(new Runnable() {
			@Override
			public void run() {
				byte[] temp = new byte[1024];
				try {
					int len;
					while ((len = pis.read(temp)) != -1) {
						System.out.println("輸入流完成一次資料寫入,資料為:"+new String(temp, 0, len));
						Thread.sleep(1000);
					}
				} catch (IOException | InterruptedException e) {
					e.printStackTrace();
				}
			}
		});

		input.start();
		output.start();
	}

}

3)位元組陣列流的作用是在位元組陣列和流之間搭建橋樑。ByteArrayInputStream的構造方法ByteArrayInputStream(byte[] buf)可以將位元組陣列構造成位元組陣列流的資料來源,從而可以通過流的方式來讀位元組陣列;ByteArrayOutputStream的作用在於可以將任意多位元組的內容多次寫入流中,最後整體轉為一個位元組陣列。

import java.io.*;
//位元組陣列輸入
 public static void byteArrayInPut(){
        String s = "aaa";
        byte[] src =  s.getBytes();
        InputStream is = null;
        is = new ByteArrayInputStream(src);
        byte[] data = new byte[3];
        int len = -1;
        try {
            while((len = is.read(data))!=-1){
               String str = new String(data,0,len);
                System.out.println(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
//位元組陣列輸出流

  public static void byteArrayOutPut(){
        byte[] destByte = null;
        ByteArrayOutputStream baos = null;
        try {
            baos = new ByteArrayOutputStream();
            String s = "eeeeeeee";
            byte[] data = s.getBytes();
            baos.write(data,0,data.length);
            baos.flush();
            //獲取資料
            destByte = baos.toByteArray();
            String str = new String(destByte,0,destByte.length);
            System.out.println(str);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 

3.

(1)輸入位元組流轉為字元流需要用到InputStreamReader的構造方法:
       InputStreamReader(InputStream in)
    其使用方法為:
InputStreamReader ins = new InputStreamReader(new  FileInputStream("c:\\text.txt"));
之後通過ins的方法就可以從字元角度來讀取檔案text.txt。
(2)輸出字元流轉為位元組流要用到OutputStreamWriter或PrintWriter的構造方法:
OutputStreamWriter(OutputStream out)
PrintWriter(OutputStream out)

其使用方法為:
OutputStreamWriter outs = new OutputStreamWriter(new FileOutputStream("c:\\text.txt"));
之後通過outs就可以直接輸出字元到text.txt檔案中。
這種轉化過程並沒有改變流的內容,只是改變了“看”流的角度。例如上面輸入流還可以再進行裝配。查閱JDK幫助文件,可發現緩衝輸入字元流的構造方法如下:BufferedReader(Reader in)
其引數說明只要是Reader的子類都可以作為BufferedReader的引數,因此可寫成:

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("c:\text.txt")));
 

4.
 過濾流在讀/寫資料的同時可以對資料進行處理,它提供了同步機制,使得某一時刻只有一個執行緒可以訪問一個I/O流,以防止多個執行緒同時對一個I/O流進行操作所帶來的意想不到的結果。類FilterInputStream和FilterOutputStream分別作為所有過濾輸入流和輸出流的父類。

  幾種常見的過濾流

         BufferedReader和BufferedWriter
    緩衝流,用於提高輸入/輸出處理的效率。

import java.io.*;
public class inDataSortMaxMinIn
{     
  public static void main(String args[])
   {	
	  try{
		  BufferedReader keyin = new BufferedReader(new 
InputStreamReader(System.in)); 
		  String c1;
		  int i=0;
		  int[] e = new int[10];		  		 
		  while(i<10){
			  try{
				c1 = keyin.readLine();
				e[i] = Integer.parseInt(c1);
				i++;
			  }			  
			  catch(NumberFormatException ee){
				  System.out.println("請輸入正確的數字!");
			  }
		  }
	  }
	  catch(Exception e){
		  System.out.println("系統有錯誤");
	  }
   }
 }



  DataInputStream 和 DataOutputStream
    不僅能讀/寫資料流,而且能讀/寫各種的java語言的基本型別,如:boolean,int,float等。

  LineNumberInputStream
    除了提供對輸入處理的支援外,LineNumberInputStream可以記錄當前的行號。

  PushbackInputStream
    提供了一個方法可以把剛讀過的位元組退回到輸入流中,以便重新再讀一遍。

  PrintStream
    列印流的作用是把Java語言的內構型別以其字元表示形式送到相應的輸出流。

import java.io.*;
 public class PrintScreen {
	 public static void main(String[] args) throws Exception {
	  PrintWriter out = new PrintWriter(new 
OutputStreamWriter(System.out), true);
 	    out.println("Hello");
	 }
 }

5.Java序列化是指把Java物件轉換為位元組序列的過程,而Java反序列化是指把位元組序列恢復為Java物件的過程。

只有實現了Serializable和Externalizable介面的類的物件才能被序列化。Externalizable介面繼承自 Serializable介面,實現Externalizable介面的類完全由自身來控制序列化的行為,而僅實現Serializable介面的類可以 採用預設的序列化方式 。

import java.io.*;
public class Student2 implements Serializable    //序列化
{
    int number=1;
    String name;
    Student2(int number,String n1)
    {   this.number = number;
        this.name = n1;
    }
    Student2()
    { this(0,""); }
    void save(String fname)
    {
        try
        {
            FileOutputStream fout = new FileOutputStream(fname);
            ObjectOutputStream out = new ObjectOutputStream(fout);
            out.writeObject(this);               //寫入物件
            out.close();
        }
        catch (FileNotFoundException fe){}
        catch (IOException ioe){}
    }
    void display(String fname)
    {
        try
        {
            FileInputStream fin = new FileInputStream(fname);
            ObjectInputStream in = new ObjectInputStream(fin);
            Student2 u1 = (Student2)in.readObject();  //讀取物件
            System.out.println(u1.getClass().getName()+"  "+
                                 u1.getClass().getInterfaces()[0]);
            System.out.println("  "+u1.number+"  "+u1.name);
            in.close();
        }
        catch (FileNotFoundException fe){}
        catch (IOException ioe){}
        catch (ClassNotFoundException ioe) {}
    }
    public static void main(String arg[])
    {
        String fname = "student2.obj"; //檔名
        Student2 s1 = new Student2(1,"Wang");
        s1.save(fname);
        s1.display(fname);
    }
}

6.File類是java.io包下代表與平臺無關的檔案和目錄的類。在程式中操作檔案和目 錄,都可以通過File類來完成。

作用:File可以實現獲取檔案和目錄屬性等功能,可以實現對檔案和目錄的建立,刪除等功能。

7.以位元組為單位讀取檔案,常用於讀二進位制檔案,如圖片、聲音、影像等檔案。
以字元為單位讀取檔案,常用於讀文字,數字等型別的檔案。
至於是否選擇用Buffer來對檔案輸入輸出流進行封裝,就要看檔案的大小,若是大檔案的讀寫,則選擇Buffer這個桶來提供檔案讀寫效率。