java基礎知識-IO流-字節流

耐得住寂寞,才能守得住繁華

1、在java中,所有的數據都是使用流讀寫的,流就像水流一樣,將數據從一個地方帶到另一個地方。
2、流是程序中的數據所經歷的的路徑,輸入流將數據從數據源傳遞給程序,而輸出流將數據發送到某個目的地。

流的分類

  1. 字節流
    字節流傳送0-255的整數。很多類型的數據都可以表示爲字節格式,包括數字數據,可執行程序,Internet通信和字節碼(java虛擬機運行的類文件)。
    實際上,每種數據都可以表示爲單個字節或一系列的字節。

  2. 字符流
    字符流是一種特殊的字符流,只能處理文本數據。它不同於字節流,因爲java支持Unicode–該標準包含很多無法用字節表示的字符。
    對於任何涉及文本的數據,都應使用字符流,這包括文本文件,Web頁,以及其他常見的數據類型。

在字節流中輸出數據主要使用OutputStream類完成,輸入則是InputStream類。
在字符流中輸出數據主要使用Writer類完成,輸入則是Reader類。
下面是他們的層次關係
IO流的繼承關係
還可以分類爲節點流和過濾流

  • 節點流:從特定地方讀寫的流類,例如:磁盤或一塊內存區域。常用的節點流包括
    (1)文 件 FileInputStream FileOutputStrean FileReader FileWriter 文件進行處理的節點流。
    (2)字符串 StringReader StringWriter 對字符串進行處理的節點流。
    (3)數 組 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter 對數組進行處理的節點流(對應的不再是文件,而是內存中的一個數組)。
    (4)管 道 PipedInputStream PipedOutputStream PipedReaderPipedWriter對管道進行處理的節點流。
  • 過濾流(包裝流):對一個已存在的流的連接和封裝,通過所封裝的流的功能調用實現數據讀寫。如BufferedReader。包裝流的構造方法總是要帶一個其他的流對象做參數。一個流對象經過其他流的多次包裝,稱爲流的鏈接。
    常用的包裝流有
    (1)緩衝流:BufferedInputStrean BufferedOutputStream BufferedReader BufferedWriter—增加緩衝功能,避免頻繁讀寫硬盤。
    (2)轉換流:InputStreamReader OutputStreamReader實現字節流和字符流之間的轉換。
    (3)數據流 DataInputStream DataOutputStream 等-提供將基礎數據類型寫入到文件中,或者讀取出來.

字節流

InputStream

  1. InputStream 是一個抽象類,不能直接通過創建這些類的對象來創建字節流,必須通過它的子類來創建。
  2. InputStream是所有輸入流的超類。

文件輸入流

文件流是最經常使用的字節流,繼承了InputStream。它用於同磁盤或其他設備中的文件交換數據,這些文件可以使用文件夾路徑和文件名來引用。

構造方法摘要

 public FileInputStream (File file)   throws FileNotFoundException
 public FileInputStream (String name)  throws FileNotFoundException
  1. 通過打開一個到實際文件的連接來創建一個 FileInputStream,該文件通過文件系統中的 File 對象 file 或者是系統中的路徑名指定。
  2. 如果指定文件不存在,或者它是一個目錄,而不是一個常規文件,抑或因爲其他某些原因而無法打開進行讀取,則拋出 FileNotFoundException。
public  static String filePath = "C:/Users/asus-pc/Desktop/javaProject/src/test";
	//路徑名中是左劃線,或者兩個右劃線
	public static void main(String[] args) throws FileNotFoundException {
          File file = new File(filePath);
          InputStream  testInput = new FileInputStream(file);
          InputStream testInput2 = new FileInputStream(filePath);
          //InputStream 是抽象類,要用它的子類進行實例化。
		
	}

方法摘要

public int read(byte[] b) throws IOException
   // 返回讀入緩衝區的字節總數如果因爲已經到達文件末尾而沒有更多的數據,則返回 -1。 
public int read() throws IOException
  //該方法返回流中的下一個字節(整數類型)。如果返回-1(這不是字節值),則表明已經達到了文件流的末尾。
public int read(byte[] b, int off, int len)  throws IOException
  //	off - 目標數組 b 中的起始偏移量,len - 讀取的最大字節數。
  // 讀入緩衝區的字節總數,如果因爲已經到達文件末尾而沒有更多的數據,則返回 -1。  
public void close()  throws IOException
  //關閉此文件輸入流並釋放與此流有關的所有系統資源。

示例

package test;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class testStream {
	public  static String filePath = "C:/Users/asus-pc/Desktop/javaProject/src/test/testStream.java";
	 //路徑名中是左劃線,或者兩個右劃線
	static InputStream  testInput = null;
	 static InputStream testInput2 =null;
	public static void main(String[] args) throws IOException {
          File file = new File(filePath);
           testInput = new FileInputStream(file);
           testInput2 = new FileInputStream(filePath);
          //InputStream 是抽象類,要用它的子類進行實例化。
          
          //第一種read方法
		byte bytes[] = new byte[(int) file.length()];
		//file.length()是爲了獲取文件的大小
		int firstSize =0;
		firstSize = testInput.read(bytes);
		System.out.println("使用第一種方法讀出來的數據字節數爲"+firstSize+"\n"+new String(bytes));
		  testInput.close();
		  
		//第二種讀方法
         int value = -1;
         int secondSize = 0;
         System.out.println("使用第二種讀法");
         while((value=testInput2.read())!=-1){
        	 secondSize++;
        	   System.out.print((char)(value));
        	   //讀到的數據爲 int型的,當返回值爲-1時,已到達文件末尾
         }
         System.out.println("通過第二種方法總共讀取了"+secondSize+"字節");
         testInput2.close();
         
         //第三種讀方法
         testInput = new FileInputStream(file);//重新打開流
         int thirdSize = 0;
         thirdSize = testInput.read(bytes, 0, (int)(file.length()));
        System.out.println("使用第三種讀法讀取的數據字節數爲"+thirdSize+"\n"+new String(bytes));
       testInput.close();   
	}

}

文件輸出流

構造方法

public FileOutputStream(File file) throws FileNotFoundException
public FileOutputStream(File file, boolean append) throws FileNotFoundException
public FileOutputStream(String name) throws FileNotFoundException
public FileOutputStream(String name,boolean append)throws FileNotFoundException

1、創建一個向具有指定 name 的文件或指定 File 對象表示的文件中寫入數據的輸出文件流。
2、當只有一個參數時,爲重新寫入,當有兩個參數時,如果第二個參數爲 true,則將字節寫入文件末尾處,而不是寫入文件開始處。

  testOutput = new FileOutputStream("C:/Users/asuspc/Desktop/javaProject/src/test/testStream2.java");
  testOutput2 = new FileOutputStream(filePath,true);
  //可以以文件路徑以及File 對象來創建FileOutputStream,第二個參數爲true的表示爲追加

方法概述

public void write(int b) throws IOException
//一個字節一個字節的寫
public void write(byte[] b) throws IOException
//將整個b數組寫進去
public void write(byte[] b,int off, int len) throws IOException
//將指定 byte 數組中從偏移量 off 開始的 len 個字節寫入此文件輸出流。
//在寫的時候,如果該文件不存在,則會嘗試創建該文件
        //第一種寫方法
        String firWrite = "first write";
        bytes=firWrite.getBytes();
        for(int i=0;i<bytes.length;i++)
        	 testOutput.write(bytes[i]);
        
        //第二種方法
        String secWrite = "second write";
       bytes=secWrite .getBytes();
        testOutput2.write(bytes);
     
        //第三種寫方法
        String thiWrite = "third write";
       bytes=thiWrite .getBytes();
        testOutput2.write(bytes,0,bytes.length); 

ByteArrayInputStream,ByteArrayOutputStream

  • 文件流是從磁盤進行讀寫,而ByteArrayInputStream,ByteArrayOutputStream是從一塊內存區域進行讀寫操作的
  • ByteArrayInputStream 包含一個內部緩衝區,該緩衝區包含從流中讀取的字節。內部計數器跟蹤 read 方法要提供的下一個字節。
  • ByteArrayOutputStream類實現了一個輸出流,其中的數據被寫入一個 byte 數組(緩衝區)。緩衝區會隨着數據的不斷寫入而自動增長。可使用 toByteArray() 和 toString() 獲取數據。
  • 當緩衝區大小不夠時,ByteArrayOutputStream是自動增長緩衝區的大小。
  • 利用ByteArrayInputStream和ByteArrayOutputStream可以實現將對象等其他類型與字節數組相互轉換。

對象轉換成數組(對象必須可以串行化)

public byte[] objectToBytes(Object obj){
		  byte bytes[] =null;
		   ByteArrayOutputStream bArrayOutputStream =new ByteArrayOutputStream();
		   try {
			ObjectOutputStream objectOutputStream =new 		 
			ObjectOutputStream(bArrayOutputStream);
		   objectOutputStream.writeObject(obj);
		   bytes =bArrayOutputStream.toByteArray();		   
		   } catch (IOException e) {
			e.printStackTrace();
		}
		   return bytes;
	}

字節數組轉換成對象

public Object bytesToObject(byte bytes[]){
		  ByteArrayInputStream bArrayInputStream =new ByteArrayInputStream(bytes);
	      Object obj =null;
		  try {
			  ObjectInputStream objectInputStream =new ObjectInputStream(bArrayInputStream);
	          obj =objectInputStream.readObject();
		  } catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return obj;  
	}

過濾流

  • 過濾流對通過現有流傳遞的信息進行修改。它是使用FilterInputStream或FilterOutStream的子類來創建,而這兩個類也繼承自InputStream,OutputStream。
  • 過濾流對基本的輸入輸出流進行包裝,從而在輸入輸出數據的同時能對所傳輸的數據做指定類型或格式的轉換,即可實現對二進制字節數據的理解和編碼轉換。
  • 例如: 緩衝輸出流BufferedOuputStream類提供和FileOutputStream同樣的寫操作方法,但所有輸出全部先寫入緩衝區中。當寫滿緩衝區或者關閉輸出流時,它再一次性輸出到節點流,或者用flush()方法主動將緩衝區輸出到流。
  • 數據輸入流DataInputStream中定義了多個針對不同類型數據的讀法,如readByte()、readBoolean()、readShort()、 readChar()、readInt()、readLong()、readFloat()、readDouble()、readLine()等。數據輸出流DataOutputStrean也有類似的方法。但我們用該流包裝節點流時,我們可以對基本數據類型進行操作。
  • 轉換流(InputStreamReader,OutputStreamWriter)能實現字節流和字符流的轉換。

緩衝流

  1. 緩衝流使用未被處理過的數據來填充緩衝區,程序需要數據時,將首先從緩衝區中查找,如果沒有找到,再到流源中查找。
  2. 緩衝字節流是使用BufferInputStream和BufferOutputStream類表示的。
緩衝流常用方法

構造方法概述

public BufferedInputStream(InputStream in)
    //爲指定的InputStream對象創建一個緩衝輸入流。
    //參數:   in - 底層輸入流。
    //默認大小爲 8192字節
public BufferedInputStream (InputStream in,int size)
//爲指定的InputStream對象創建一個緩衝區大小爲size的緩衝輸入流。
BufferedInputStream  bufTest = new BufferedInputStream (testInput );

爲testInput 創建緩衝輸入流

方法概述

public int read() throws IOException
public int read(byte[] b, int off, int len) throws IOException

和FileInputStream的用法一致

數據流

要處理未被表示爲字節或字符的數據,可以使用數據輸入流和數據輸出流。這些流對字節流進行過濾,以便能夠直接讀寫如下基本數據類型:boolean,byte,double,float,int,long和short

數據流常用方法

構造方法概述

public DataInputStream(InputStream in)

使用指定的底層 InputStream 創建一個 DataInputStream。

方法概述
可用於數據輸入與數據輸出的讀寫方法如下
readBoolean() , writeBoolean(boolean)
readByte() , writeByte(integer);
readDouble() , writeDouble(double)
readFloat() , writeFloat(float)
readInt() , writeInt(int)
readLong() , writeLong(long)
readShort() , writeShort(int)

下個博客在總結字符流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章