FileInputStream/FileOutputStream的應用

來源:互聯網
上載者:User

這是一對繼承於InputStream和OutputStream的類,用於本地檔案讀寫(二進位格式讀寫並且是順序讀寫,讀和寫要分別建立出不同的檔案流對象);

本地檔案讀寫編程的基本過程為:

①  組建檔案流對象(對檔案讀操作時應該為FileInputStream類,而檔案寫應該為FileOutputStream類);

②  調用FileInputStream或FileOutputStream類中的功能函數如read()、write(int b)等)讀寫檔案內容;

③  關閉檔案(close())。

執行個體:流檔案讀寫

流檔案的單元是位元組,所以它不但可以讀寫文字檔,也可以讀寫圖片、聲音、影像檔案,這種特點非常有用,因為我們可以把這種檔案變成流,然後在網路上傳輸。

問題是有了通用的流檔案以後,為什麼還要專門的字元流呢?這是因為文本可以用不同的方式儲存,可以是普通的文本(UTF-8編碼方式),ASCII文本和Unicode文本,字元流對象可以進行必要的轉換,從而讀出正確的文本。

有人認為流檔案不能讀寫文字檔,這其實是個誤會,因為文字檔本質上也是由位元組組成的,當然是流檔案的一種。作為讀寫檔案的全體,這是沒問題的,但是,如果要處理每次讀入的內容,就最好使用字元流。

所以在文字檔處理時,使用字元流是個最常用的方法。

範例:

import java.io.*;

public class FileStreamDemo {

public static void main(String[] args) throws IOException {

//建立兩個檔案,face.gif是已經存在檔案,newFace.gif是新建立的檔案

File inFile = new File("face.gif");

File outFile = new File("newFace.gif");

//建立流檔案讀入與寫出類

FileInputStream inStream = new FileInputStream(inFile);

FileOutputStream outStream = new FileOutputStream(outFile);

//通過available方法取得流的最大字元數

byte[] inOutb = new byte[inStream.available()];

inStream.read(inOutb);  //讀入流,儲存在byte數組

outStream.write(inOutb);  //寫出流,儲存在檔案newFace.gif中

inStream.close();

outStream.close();

}

}

執行個體:讀寫任意大檔案應用

因為byte數組最大儲存值不超過64M,所以當一個檔案大於60M 的時候,需要分開幾個流操作。我們把上面的程式作一個修改,就可以寫入任意大小的檔案。這個程式應用了FileInputStream類的方法如下:

read(byte[] b,int off,int len)

把特定位置的流內容讀入數組,已經讀入byte[]數組的內容,會在流檔案中刪除。

程式啟動並執行結果會產生一個新檔案。

範例:

import java.io.*;

public class FileStreamDemo2 {

public static void main(String[] args) throws IOException {

//建立兩個檔案

File inFile = new File("tcty36.rm");

File outFile = new File("newtcty36.rm");

//最大的流為60Mb,當檔案的容量大於60Mb的時候便分開流

final int MAX_BYTE = 60000000;

long streamTotal = 0;  //接受流的容量

int streamNum = 0;  //流需要分開的數量

int leave = 0;  //檔案剩下的字元數

byte[] inOutb;  //byte數組接受檔案的資料

//建立流檔案讀入與寫出類

FileInputStream inStream = new FileInputStream(inFile);

FileOutputStream outStream = new FileOutputStream(outFile);

//通過available方法取得流的最大字元數

streamTotal = inStream.available();

//取得流檔案需要分開的數量

streamNum = (int)Math.floor(streamTotal/MAX_BYTE);

//分開檔案之後,剩餘的數量

leave = (int)streamTotal % MAX_BYTE;

//檔案的容量大於60Mb時進入迴圈

if (streamNum > 0) {

for(int i = 0; i < streamNum; ++i){

inOutb = new byte[MAX_BYTE];

//讀入流,儲存在byte數組

inStream.read(inOutb, 0, MAX_BYTE);

outStream.write(inOutb);  //寫出流

outStream.flush();  //更新寫出的結果

}

}

//寫出剩下的流資料

inOutb = new byte[leave];

inStream.read(inOutb, 0, leave);

outStream.write(inOutb);

outStream.flush();

inStream.close();

outStream.close();

}

}

六、管道PipedInputStream/PipedOutputStream類:

當需要在兩個線程中讀寫資料的時候,由於線程的並發執行,讀寫的同步問題可能會發生困難,這時候可以使用管道,管道事實上是一個隊列。

管道是由系統維護的一個緩衝區,當然程式員也可以自己直接指定該緩衝區的大小(只需要設定管道流類中的PIPE_SIZE屬性的值)。當生產者生產出資料後,只需要將資料寫入管道中,消費者只需要從管道中讀取所需要的資料。利用管道的這種機制,可以將一個線程的輸出結果直接連接到另一個線程的輸入連接埠,實現兩者之間的資料直接傳送。

線程1
線程2
臨時檔案
管道

1.管道的串連:

方法之一是通過建構函式直接將某一個程式的輸出作為另一個程式的輸入,在定義對象時指明目標管道對象

PipedInputStream pInput=new PipedInputStream();

PipedOutputStream pOutput= new PipedOutputStream(pInput);

方法之二是利用雙方類中的任一個成員函數 connect()相串連

PipedInputStream pInput=new PipedInputStream();

PipedOutputStream pOutput= new PipedOutputStream();

pinput.connect(pOutput);

2.管道的輸入與輸出:

輸出管道對象調用write()成員函數輸出資料(即向管道的輸入端發送資料);而輸入管道對象調用read()成員函數可以讀起資料(即從輸出管道中獲得資料)。這主要是藉助系統所提供的緩衝機制來實現的。

執行個體:Java的管道的輸入與輸出

import java.io.*;

public class PipedIO //程式運行後將sendFile檔案的內容拷貝到receiverFile檔案中

{

public static void main(String args[])

{

try

{

//構造讀寫的管道流對象

PipedInputStream pis=new PipedInputStream();

PipedOutputStream pos=new PipedOutputStream();

//實現關聯

pos.connect(pis);

//構造兩個線程,並且啟動。

new Sender(pos,"c:\\text2.txt").start();

new Receiver(pis,"c:\\text3.txt").start();

}

catch(IOException e)

{

System.out.println("Pipe Error"+ e);

}

}

}

//線程發送

class Sender extends Thread

{

PipedOutputStream pos;

File file;

//構造方法

Sender(PipedOutputStream pos, String fileName)

{

this.pos=pos;

file=new File(fileName);

}

//線程運行方法

public void run()

{

try

{

//讀檔案內容

FileInputStream fs=new FileInputStream(file);

int data;

while((data=fs.read())!=-1)

{

//寫入管道始端

pos.write(data);

}

pos.close();

}

catch(IOException e)

{

System.out.println("Sender Error" +e);

}

}

}

//線程讀

class Receiver extends Thread

{

PipedInputStream pis;

File file;

//構造方法

Receiver(PipedInputStream pis, String fileName)

{

this.pis=pis;

file=new File(fileName);

}

//線程運行

public void run()

{

try

{

//寫檔案流對象

FileOutputStream fs=new FileOutputStream(file);

int data;

//從管道末端讀

while((data=pis.read())!=-1)

{

//寫入本地檔案

fs.write(data);

}

pis.close();

}

catch(IOException e)

{

System.out.println("Receiver Error" +e);

}

}

}

七、隨機檔案讀寫:RandomAccessFile類

它直接繼承於Object類而非InputStream/OutputStream類,從而可以實現讀寫檔案中任何位置中的資料(只需要改變檔案的讀寫位置的指標)。

編程步驟:

① 產生流對象並且指明讀寫類型;

② 移動讀寫位置;

③ 讀寫檔案內容;

④ 關閉檔案。

另外由於RandomAccessFile類實現了DataOutput與DataInput介面,因而利用它可以讀寫Java中的不同類型的基本類型資料(比如採用readLong()方法讀取長整數,而利用readInt()方法可以讀出整數值等)。

程式執行個體:

利用隨機資料流RandomAccessFile類來實現記錄使用者在鍵盤的輸入,每執行一次,將使用者的鍵盤輸入儲存在指定的UserInput.txt檔案中。

import java.io.*;

public class RandomFileRW

{

public static void main(String args[])

{

StringBuffer buf=new StringBuffer();

char ch;

try

{

while( (ch=(char)System.in.read()) !='\n')

{

buf.append(ch);

}

//讀寫方式可以為"r" or "rw"

RandomAccessFile myFileStream=new RandomAccessFile("c:\\UserInput.txt","rw");

myFileStream.seek(myFileStream.length()) ;

myFileStream.writeBytes(buf.toString());

//將使用者從鍵盤輸入的內容添加到檔案的尾部

myFileStream.close();

}

catch(IOException e)

{

}

}

}

八、DataInput/DataOutput介面:

實現與機器無關的各種資料格式讀寫(如readChar() 、readInt()、readLong()、readFloat(),而readLine()將返回一個String)。其中RandomAccessFile類實現了該介面,具有比FileInputStream或FileOutputStream類更靈活的資料讀寫方式。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.