教你完全理解IO流裡的 read(),read(byte[]),read(byte[],int off,int len)以及write
阿新 • • 發佈:2019-01-06
好的我們先來講它們的作用,然後再用程式碼來實現給大家看
read():
1.從讀取流讀取的是一個一個位元組
2.返回的是位元組的(0-255)內的位元組值
3.讀一個下次就自動到下一個,如果碰到-1說明沒有值了.
read(byte[] bytes)
1.從讀取流讀取一定數量的位元組,如果比如檔案總共是102個位元組
2.我們定義的陣列長度是10,那麼預設前面10次都是讀取10個長度
3.最後一次不夠十個,那麼讀取的是2個
4.這十一次,每次都是放入10個長度的陣列.
read(byte[] bytes,int off ,int len)
1.從讀取流讀取一定數量的位元組,如果比如檔案總共是102個位元組
2.我們定義的陣列長度是10,但是這裡我們寫read(bytes,0,9)那麼每次往裡面新增的(將只會是9個長度),就要讀12次,最後一次放入3個.
3.所以一般讀取流都不用這個而是用上一個方法:read(byte[]);
下面講解write
write(int i);
直接往流寫入位元組形式的(0-255)int值.
write(byte[] bytes);
往流裡邊寫入緩衝位元組陣列中的所有內容,不滿整個陣列長度的”空餘內容”也會加入,這個下面重點講,
write(byte[] bytes,int off,int len);
1.這個是更嚴謹的寫法,在外部定義len,然後每次len(為的是最後一次的細節長度
2.如上述read(bytes),前面每次都放入十個,第十一次放入的是2個,如果用第二種write(bytes),將會寫入輸出流十一次,每次寫入十個長度,造成後面有8個空的,比原來的內容多了
3.所以用write(byte[] bytes,int off,int len);就不會出現多出來的空的情況,因為最後一次len不同
下面是詳細的程式碼
public class Test{
public static void main(String[] args) throws Exception {
UseTimeTool.getInstance().start();
FileInputStream fis = new FileInputStream("D:\\1.mp3");
FileOutputStream fos = new FileOutputStream("D:\\1copy.mp3");
//(PS:一下3個大家分開來寫和測試,為了方便我都列出來了)
/*--------------不使用緩衝--------------*/
//如果不緩衝,花了差不多14"秒"
int len = -1;
while ((len = fis.read()) != -1) {
//這裡就不是長度的問題了,而是讀取的位元組"內容",讀到一個寫一個,相當慢.
System.out.println("len : "+ len);
fos.write(len);
}
/*--------------使用緩衝--------------*/
//緩衝方法複製歌曲用了不到20"毫秒"
//建立一個長度為1024的位元組陣列,每次都讀取5kb,目的是快取,如果不用緩衝區,用fis.read(),就會效率低,一個一個讀位元組,緩衝區是一次讀5000個
byte[] bytes = new byte[1024*5];
//每次都是從讀取流中讀取(5k)長度的資料,然後再寫到檔案去(5k的)資料,注意,每次讀取read都會不同,是獲取到下一個,直到後面最後一個.
while (fis.read(bytes)!=-1) {
//write是最追加到檔案後面,所以直接每次添5K.
fos.write(bytes);
}
/*--------------解釋len--------------*/
//告訴你為什麼用len
byte[] bytes = new byte[1024*5];
int len = -1;
//解釋這個fis.read(bytes)的意思:從讀取流"讀取陣列長度"的資料(列印len可知),並放入陣列
while ((len = fis.read(bytes,0,1024)) != -1) {
//雖然陣列長度的*5,但是這裡我們設定了1024所以每次輸出1024
System.out.println("len : "+ len);
//因為每次得到的是新的陣列,所以每次都是新陣列的"0-len"
fos.write(bytes,0,len);
}
fis.close();
fos.close();
UseTimeTool.getInstance().stop();
}
}
為了方便大家,也給大家一個統計時間的工具類
class UseTimeTool {
private static UseTimeTool utt = new UseTimeTool();
private UseTimeTool() {
}
public static UseTimeTool getInstance() {
return utt;
}
private long start;
public void start() {
start = System.currentTimeMillis();
}
public void stop() {
long end = System.currentTimeMillis();
System.out.println("所用時間 : " + (end - start) + "毫秒");
}
}
好了最後一個:len問題 最後多出陣列不滿的部分我特再寫一個出來給大家分析
首先,文字的內容是
public class Test{
public static void main(String[] args) throws Exception {
UseTimeTool.getInstance().start();
FileInputStream fis = new FileInputStream("D:\\a.txt");
FileOutputStream fos = new FileOutputStream("D:\\acopy.txt");
不使用len:
byte[] bytes = new byte[1024*5];
while (fis.read(bytes)!=-1) {
fos.write(bytes);
}
得到的效果:
發現後續後很多的空部分,所以說不嚴謹
使用len:
byte[] bytes = new byte[1024*5];
int len = -1;
while ((len = fis.read(bytes,0,1024)) != -1) {
fos.write(bytes,0,len);
}
得到的效果
和原來一模一樣,講了那麼多就是希望能幫助大家真正的理解.