java基礎知識-IO流-位元組流
耐得住寂寞,才能守得住繁華
流
1、在java中,所有的資料都是使用流讀寫的,流就像水流一樣,將資料從一個地方帶到另一個地方。
2、流是程式中的資料所經歷的的路徑,輸入流將資料從資料來源傳遞給程式,而輸出流將資料傳送到某個目的地。
流的分類
-
位元組流
位元組流傳送0-255的整數。很多型別的資料都可以表示為位元組格式,包括數字資料,可執行程式,Internet通訊和位元組碼(java虛擬機器執行的類檔案)。
實際上,每種資料都可以表示為單個位元組或一系列的位元組。 -
字元流
字元流是一種特殊的字元流,只能處理文字資料。它不同於位元組流,因為java支援Unicode–該標準包含很多無法用位元組表示的字元。
對於任何涉及文字的資料,都應使用字元流,這包括文字檔案,Web頁,以及其他常見的資料型別。
在位元組流中輸出資料主要使用OutputStream類完成,輸入則是InputStream類。
在字元流中輸出資料主要使用Writer類完成,輸入則是Reader類。
下面是他們的層次關係
還可以分類為節點流和過濾流
- 節點流:從特定地方讀寫的流類,例如:磁碟或一塊記憶體區域。常用的節點流包括
(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
- InputStream 是一個抽象類,不能直接通過建立這些類的物件來建立位元組流,必須通過它的子類來建立。
- InputStream是所有輸入流的超類。
檔案輸入流
檔案流是最經常使用的位元組流,繼承了InputStream。它用於同磁碟或其他裝置中的檔案交換資料,這些檔案可以使用資料夾路徑和檔名來引用。
構造方法摘要
public FileInputStream (File file) throws FileNotFoundException
public FileInputStream (String name) throws FileNotFoundException
- 通過開啟一個到實際檔案的連線來建立一個 FileInputStream,該檔案通過檔案系統中的 File 物件 file 或者是系統中的路徑名指定。
- 如果指定檔案不存在,或者它是一個目錄,而不是一個常規檔案,抑或因為其他某些原因而無法開啟進行讀取,則丟擲 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)能實現位元組流和字元流的轉換。
緩衝流
- 緩衝流使用未被處理過的資料來填充緩衝區,程式需要資料時,將首先從緩衝區中查詢,如果沒有找到,再到流源中查詢。
- 緩衝位元組流是使用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)
下個部落格在總結字元流。