天天看點

IO流--基礎流FileInputStream和FileOutputStream的使用

                                基礎流的簡單操作

    之前學到的File我們隻能操作檔案夾和檔案,卻不能操作裡面的内容。今天通過學習IO流之後,我們就可以操作檔案裡面的内容了。在Java中,處理位元組流的兩個基礎的類是InputStream和OutputStream,而用于處理字元流的兩個基礎的類是Reader和Writer。是以其他的流類都是以這4個類為基礎。首先就說一下InputStream和OutputStream。

FileInoutStream和FileOutputStream分别是InputStream和OutputStream的直接子類,我們可以叫它們為基礎流或者低級流,基本流中構造中參數是媒體。

1. InputStream的方法

        read():讀入一個位元組并傳回,包裝為int,傳回-1表示已讀不到

        close():關閉資源

首先從讀檔案的内容開始,例如我們先在D盤建立一個檔案a.txt在裡面寫上abcde,那麼我們怎麼把這些内容讀出來呢?看下面的代碼。

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStream;

publicclass Test {

publicstaticvoid main(String[] args) {

InputStream is = null;

try {// 輸入流檔案必須存在

is = new FileInputStream("d:\\a.txt");

int i = is.read();//讀第一個位元組

System.out.println(i);//輸出對應的内容,是int類型的如果想輸出原來的内容

//把類型轉換一下就可以了

System.out.println((char)i);

//我們把兩個異常合并到一起

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

}finally{

try {//關閉資源,同樣需要抛出異常

is.close();

}

執行結果:97

a

另外的方法:

read(byte[] b) 一次讀入盡可能多的位元組去填滿位元組數組b,傳回實際讀到的位元組數,-1表示已讀不到。

read(byte[] b, int off, int len) 一次讀入盡可能多的位元組去填滿位元組數組b從off開始的len個空間。

如果我們想把abcde全部都讀出來應該怎麼辦呢?這時我們可以借助循環,因為在read()方法中-1表示讀不到了,是以我們可以這麼做

int i = 0;

while((i=is.read())!=-1){//如果不是-1代表下面還有位元組

System.out.print((char)i);

執行結果:abcde

讀的操作我們已經做到了,接下來就是往檔案裡面寫内容。這時我們就需要使用OutpetStream這個流類。OutputStream類提供的方法:

write():寫一個位元組到流中

write(byte[] b):将位元組數組中的資料寫入流中

write(byte[] b, int off, int len):将位元組數組中從off開始的length個位元組寫入到流中

flush():将緩沖中的位元組立即發送到流中,同時清空緩沖

close():關閉輸出流

寫的操作和讀差別不大,看一下代碼:

import java.io.FileOutputStream;

import java.io.OutputStream;

OutputStream os = null;

try {// 輸出流:自己會建立一個檔案

// true表示追加 false表示覆寫 預設是false

os = new FileOutputStream("d:\\b.txt",true);

os.write(97);//

//下面的這兩個我們隻需要寫一個就行了

//os.flush();

os.close();

執行結果根據我們執行的次數而定,因為我們加了true,如果執行一次結果就是a,兩次就是aa,以此類推。

如果我們想把a.txt的内容複制到b.txt中應該怎麼做呢?思路就是每當讀一個a.txt中的位元組,就往b.txt裡面寫。代碼也非常簡單。

package day11;

import java.io.File;

while((i = is.read())!=-1){

char ch = (char)i;

os = new FileOutputStream(new File("d:\\b.txt"),true);

os.write(ch);

結果當然就是b.txt裡面也是abcde

上面我們實作了檔案内容的複制,下面我們來完成壓縮檔案複制的操作,有了上面的代碼我們會有一些思路。在下面的代碼中為了更清晰的展現代碼,我們将抛出異常都交給函數來完成,不再自己處理,但是不建議這樣,現在隻是為了讓代碼清晰,看下面代碼:

publicclass TestCopyFile {

publicstaticvoid main(String[] args) throws IOException {

//調用下面的方法,左面是以存在的壓縮包,右面是複制生成的壓縮包

copyFile("d:\\day02.rar","d:\\test.rar");

//定義一個方法

publicstaticvoid copyFile(String file1,String file2) throws IOException{

FileInputStream fis = new FileInputStream(new File(file1));

FileOutputStream fos = new FileOutputStream(new File(file2));

int b = 0;

// 讀源檔案,将讀入的每個位元組依次寫入目标檔案

while((b=fis.read())!=-1){

fos.write(b);

// 流操作的最後一定要關閉

fis.close();

fos.close();

執行結果:在D盤有一個test.rar的壓縮包,當然我們可以根據自己電腦來決定複制什麼檔案,如果檔案很大的話,我們可以清楚的看到test.rar的大小會逐漸增大,這是因為我們是按位元組來複制的,很顯然這種複制方法是非常慢的,怎麼提高複制的速度呢?一起看下吧!

下面是改進的方法,改動的地方不是很大

intb = 0;

//定義一個8K的數組

byte[] arrByte = newbyte[8*1024];

// 讀源檔案,将讀入的每個位元組依次寫入目标檔案,按每8K來複制

while((b=fis.read(arrByte))!=-1){

fos.write(arrByte);

執行結果:如果檔案很大的話,我們可以看到和上面的差別,就是複制速度變快了。

但是我們會發現一個問題,那就是複制之後的test.rar變大了一點,這是因為我們是按每8k來複制的,當day02.rar末尾的地方不夠8k時,仍然會按照8k來複制,這樣最後的8k裡面就會自動填入資料,是以變大了,怎樣解決這個問題呢?也很容易,我們隻需要将上面的