4.4.2 InputStream 和OutputStream

 1.InputStream

◇ 從流中讀取數(shù)據(jù):
int read( ); //讀取一個字節(jié),返回值為所讀的字節(jié)
int read( byte b[ ] ); //讀取多個字節(jié),放置到字節(jié)數(shù)組b中,通常
//讀取的字節(jié)數(shù)量為b的長度,返回值為實(shí)際
//讀取的字節(jié)的數(shù)量

int read( byte b[ ], int off, int len ); //讀取len個字節(jié),放置
//到以下標(biāo)off開始字節(jié)
//數(shù)組b中,返回值為實(shí)
//際讀取的字節(jié)的數(shù)量

int available( );   //返回值為流中尚未讀取的字節(jié)的數(shù)量
long skip( long n ); //讀指針跳過n個字節(jié)不讀,返回值為實(shí)際
//跳過的字節(jié)數(shù)量


◇ 關(guān)閉流:
close( ); //流操作完畢后必須關(guān)閉

◇ 使用輸入流中的標(biāo)記:
void mark( int readlimit ); //記錄當(dāng)前讀指針?biāo)谖恢茫瑀eadlimit
//表示讀指針讀出
readlimit個字節(jié)后
//所標(biāo)記的指針位置才失效

void reset( );     //把讀指針重新指向用mark方法所記錄的位置
boolean markSupported( ); //當(dāng)前的流是否支持讀指針的記錄功能

有關(guān)每個方法的使用,詳見java API。


2.OutputStream

◇ 輸出數(shù)據(jù):
void write( int b );   //往流中寫一個字節(jié)b
void write( byte b[ ] ); //往流中寫一個字節(jié)數(shù)組b
void write( byte b[ ], int off, int len ); //把字節(jié)數(shù)組b中從
//下標(biāo)off開始,長度為len的字節(jié)寫入流中


◇ flush( )       //刷空輸出流,并輸出所有被緩存的字節(jié)
由于某些流支持緩存功能,該方法將把緩存中所有內(nèi)容強(qiáng)制輸出到流中。

◇ 關(guān)閉流:
close( );       //流操作完畢后必須關(guān)閉

4.4.3 I/O中的例外

  進(jìn)行I/O操作時可能會產(chǎn)生I/O例外,屬于非運(yùn)行時例外,應(yīng)該在程序中處理。如:FileNotFoundException, EOFException, IOException

4.5 文件處理

I/O處理中,最常見的是對文件的操作,java.io包中有關(guān)文件處理的類有:File、FileInputStream、 FileOutputStream、RamdomAccessFile和FileDescriptor;接口有:FilenameFilter。

4.5.1 文件描述

類File提供了一種與機(jī)器無關(guān)的方式來描述一個文件對象的屬性。下面我們介紹類File中提供的各種方法。

 ◇ 文件或目錄的生成

public File(String path);/*如果path是實(shí)際存在的路徑,則該File對象
/*表示的是目錄;如果path是文件名,則該File對象表示的是文件。*/

public File(String path,String name);//path是路徑名,name是文件名
public File(File dir,String name);//dir是路徑名,name是文件名

◇ 文件名的處理

String getName( ); //得到一個文件的名稱(不包括路徑)
String getPath( ); //得到一個文件的路徑名
String getAbsolutePath( );//得到一個文件的絕對路徑名
String getParent( ); //得到一個文件的上一級目錄名
String renameTo(File newName); //將當(dāng)前文件名更名為給定文件的
完整路徑

◇ 文件屬性測試

boolean exists( ); //測試當(dāng)前File對象所指示的文件是否存在
boolean canWrite( );//測試當(dāng)前文件是否可寫
boolean canRead( );//測試當(dāng)前文件是否可讀
boolean isFile( ); //測試當(dāng)前文件是否是文件(不是目錄)
boolean isDirectory( ); //測試當(dāng)前文件是否是目錄

◇ 普通文件信息和工具

long lastModified( );//得到文件最近一次修改的時間
long length( ); //得到文件的長度,以字節(jié)為單位
boolean delete( ); //刪除當(dāng)前文件

◇ 目錄操作

boolean mkdir( ); //根據(jù)當(dāng)前對象生成一個由該對象指定的路徑
String list( ); //列出當(dāng)前目錄下的文件

【例4-3】
import java.io.*; //引入java.io包中所有的類
public class FileFilterTest{
public static void main(String args[]){
File dir=new File("d://ex"); //用File 對象表示一個目錄
Filter filter=new Filter("java"); //生成一個名為java的過濾器
System.out.println("list java files in directory "+dir);
String files[]=dir.list(filter); //列出目錄dir下,文件后綴名
為java的所有文件

for(int i=0;i<files.length;i++){
File f=new File(dir,files[i]); //為目錄dir 下的文件或目錄
創(chuàng)建一個File 對象

if(f.isFile()) //如果該對象為后綴為java的文件,
則打印文件名

System.out.println("file "+f);
else
System.out.println("sub directory "+f ); //如果是目錄
則打印目錄名

}
}
}
class Filter implements FilenameFilter{
String extent;
Filter(String extent){
this.extent=extent;
}
public boolean accept(File dir,String name){
return name.endsWith("."+extent); //返回文件的后綴名
}
}

 

 

其他內(nèi)容請看:

http://www.bc-cn.net/Article/kfyy/java/jc/200410/81_4.html

補(bǔ)充日期: 2005-03-15 10:31:37

4.5.2 文件的順序處理

類FileInputStream和FileOutputStream用來進(jìn)行文件I/O處理,由它們所提供的方法可以打開本地主機(jī)上的文件,并進(jìn)行 順序的讀/寫。例如,下列的語句段是順序讀取文件名為text的文件里的內(nèi)容,并顯示在控制臺上面,直到文件結(jié)束為止。

  FileInputStream fis;
try{
fis = new FileInputStream( "text" );
System.out.print( "content of text is : ");
int b;
while( (b=fis.read())!=-1 ) //順序讀取文件text里的內(nèi)容并賦值
給整型變量b,
直到文件結(jié)束為止。
{              
System.out.print( (char)b );
}
}catch( FileNotFoundException e ){
System.out.println( e );
}catch( IOException e ){
System.out.println( e );
}

4.5.3 隨機(jī)訪問文件

對于InputStream 和OutputStream 來說,它們的實(shí)例都是順序訪問流,也就是說,只能對文件進(jìn)行順序地讀/寫。隨機(jī)訪問文件則允許對文件內(nèi)容進(jìn)行隨機(jī)讀/寫。在java中,類RandomAccessFile 提供了隨機(jī)訪問文件的方法。類RandomAccessFile的聲明為:
public class RandomAccessFile extends Object implements DataInput, DataOutput

  接口DataInput 中定義的方法主要包括從流中讀取基本類型的數(shù)據(jù)、讀取一行數(shù)據(jù)、或者讀取指定長度的字節(jié)數(shù)。如:readBoolean( )、readInt( )、readLine( )、readFully( ) 等。

接口DataOutput 中定義的方法主要是向流中寫入基本類型的數(shù)據(jù)、或者寫入一定長度的字節(jié)數(shù)組。如:writeChar( )、writeDouble( )、write( ) 等。 下面詳細(xì)介紹RandomAccessFile類中的方法。

◇ 構(gòu)造方法:
RandomAccessFile(String name,String mode); //name是文件名,mode
//是打開方式,例如"r"表示只讀,"rw"表示可讀寫,"

RandomAccessFile(File file,String mode); //file是文件對象

◇ 文件指針的操作
long getFilePointer( ); //用于得到當(dāng)前的文件指針
void seek( long pos ); //用于移動文件指針到指定的位置
int skipBytes( int n ); //使文件指針向前移動指定的n個字節(jié)

4.6 過濾流

過濾流在讀/寫數(shù)據(jù)的同時可以對數(shù)據(jù)進(jìn)行處理,它提供了同步機(jī)制,使得某一時刻只有一個線程可以訪問一個I/O流,以防止多個線程同時對一個I/O流進(jìn)行 操作所帶來的意想不到的結(jié)果。類FilterInputStream和FilterOutputStream分別作為所有過濾輸入流和輸出流的父類

 過濾流類層次:

        java.lang.Object
  |
  +----java.io.InputStream
  |
  +----java.io.FilterInputStream



為了使用一個過濾流,必須首先把過濾流連接到某個輸入/出流上,通常通過在構(gòu)造方法的參數(shù)中指定所要連接的輸入/出流來實(shí)現(xiàn)。例如:

FilterInputStream( InputStream in );
FilterOutputStream( OutputStream out );

4.6.1 幾種常見的過濾流

  ◇ BufferedInputStream和BufferedOutputStream
緩沖流,用于提高輸入/輸出處理的效率。

◇ DataInputStream 和 DataOutputStream
不僅能讀/寫數(shù)據(jù)流,而且能讀/寫各種的java語言的基本類型,如:boolean,int,float等。

◇ LineNumberInputStream
除了提供對輸入處理的支持外,LineNumberInputStream可以記錄當(dāng)前的行號。

◇ PushbackInputStream
提供了一個方法可以把剛讀過的字節(jié)退回到輸入流中,以便重新再讀一遍。

◇ PrintStream
打印流的作用是把Java語言的內(nèi)構(gòu)類型以其字符表示形式送到相應(yīng)的輸出流。

4.7 字符流的處理

java中提供了處理以16位的Unicode碼表示的字符流的類,即以Reader和Writer 為基類派生出的一系列類。

4.7.1 Reader和Writer

   這兩個類是抽象類,只是提供了一系列用于字符流處理的接口,不能生成這兩個類的實(shí)例,只能通過使用由它們派生出來的子類對象來處理字符流。

1.Reader類是處理所有字符流輸入類的父類。

◇ 讀取字符
public int read() throws IOException; //讀取一個字符,返回值為讀取的字符
public int read(char cbuf[]) throws IOException; /*讀取一系列字符到數(shù)組cbuf[]中,返回值為實(shí)際讀取的字符的數(shù)量*/
public abstract int read(char cbuf[],int off,int len) throws IOException;
/*讀取len個字符,從數(shù)組cbuf[]的下標(biāo)off處開始存放,返回值為實(shí)際讀取的字符數(shù)量,該方法必須由子類實(shí)現(xiàn)*/

◇ 標(biāo)記流
public boolean markSupported(); //判斷當(dāng)前流是否支持做標(biāo)記
public void mark(int readAheadLimit) throws IOException;
//給當(dāng)前流作標(biāo)記,最多支持readAheadLimit個字符的回溯。
public void reset() throws IOException; //將當(dāng)前流重置到做標(biāo)記處

◇ 關(guān)閉流
public abstract void close() throws IOException;

2. Writer類是處理所有字符流輸出類的父類。

◇ 向輸出流寫入字符
public void write(int c) throws IOException;
//將整型值c的低16位寫入輸出流

public void write(char cbuf[]) throws IOException;
//將字符數(shù)組cbuf[]寫入輸出流

public abstract void write(char cbuf[],int off,int len) throws IOException;
//將字符數(shù)組cbuf[]中的從索引為off的位置處開始的len個字符寫入輸出流
public void write(String str) throws IOException;
//將字符串str中的字符寫入輸出流
public void write(String str,int off,int len) throws IOException;
//將字符串str 中從索引off開始處的len個字符寫入輸出流

◇ flush( )
刷空輸出流,并輸出所有被緩存的字節(jié)。

◇ 關(guān)閉流
public abstract void close() throws IOException;

補(bǔ)充日期: 2005-03-15 10:39:31

 

關(guān)于 java IO 流 ;這個也不錯,只是拷貝不下來。

http://edu.cn700.com/Print.asp?ArticleID=18540

補(bǔ)充日期: 2005-03-15 10:45:25

4.7.2 InputStreamReader和OutputStreamWriter

java.io包中用于處理字符流的最基本的類,用來在字節(jié)流和字符流之間作為中介。

  ◇ 生成流對象
  public InputStreamReader(InputStream in);
/*in是字節(jié)流,而InputStreamReader是字符流,但是其來源是字節(jié)流in,
因此InputStreamReader就可以把字節(jié)流in轉(zhuǎn)換成字符流處理。/*


public InputStreamReader(InputStream in,String enc) throws UnsupportedEncodingException;
/*enc是編碼方式,就是從字節(jié)流到字符流進(jìn)行轉(zhuǎn)換時所采用的編碼方式,
例如 ISO8859-1,UTF-8,UTF-16等等*/


public OutputStreamWriter(OutputStream out);
/*out是字節(jié)流,而OutputStreamReader是字符流 */

public OutputStreamWriter(OutputStream out,String enc) throws UnsupportedEncodingException; //enc是編碼方式

InputStreamReader和OutputStreamWriter的方法:

◇ 讀入和寫出字符
基本同Reader和Writer。

◇ 獲取當(dāng)前編碼方式
public String getEncoding();

◇ 關(guān)閉流
public void close() throws IOException;

4.7.3 BufferedReader和BufferedWriter

 ◇ 生成流對象

public BufferedReader(Reader in); //使用缺省的緩沖區(qū)大小
public BufferedReader(Reader in, int sz); //sz為緩沖區(qū)的大小
public BufferedWriter(Writer out);
public BufferedWriter(Writer out, int sz);

◇ 讀入/寫出字符

除了Reader和Writer中提供的基本的讀寫方法外,增加對整行字符的處理。
public String readLine() throws IOException; //讀一行字符
public void newLine() throws IOException; //寫一行字符

【例4-4】


import java.io.*;
public class NumberInput{
public static void main(String args[]){
try{
InputStreamReader ir;
BufferedReader in;
ir=new InputStreamReader(System.in);
//從鍵盤接收了一個字符串的輸入,并創(chuàng)建了一個字符輸入流的對象
in=new BufferedReader(ir);
String s=in.readLine();
//從輸入流in中讀入一行,并將讀取的值賦值給字符串變量s
System.out.println("Input value is: "+s);
int i = Integer.parseInt(s);//轉(zhuǎn)換成int型
i*=2;
System.out.println("Input value changed after doubled: "+i);
}catch(IOException e)
{System.out.println(e);}
}
}

運(yùn)行結(jié)果

D:\>java NumberInput
123
Input value is 123
Input value changed after doubled: 246




注意:在讀取字符流時,如果不是來自于本地的,比如說來自于網(wǎng)絡(luò)上某處的與本地編碼方式不同的機(jī)器,那么我們在構(gòu)造輸入流時就不能簡單地使用本地缺省的編碼方式,否則讀出的字符就不正確;為了正確地讀出異種機(jī)上的字符,我們應(yīng)該使用下述方式構(gòu)造輸入流對象:

ir = new InputStreamReader(is, "8859_1");

采用ISO 8859_1編碼方式,這是一種映射到ASCII碼的編碼方式,可以在不同平臺之間正確轉(zhuǎn)換字符。

補(bǔ)充日期: 2005-03-15 10:56:05

4.8 對象的串行化(Serialization)

4.8.1 串行化的定義

  1. 什么是串行化

對象的壽命通常隨著生成該對象的程序的終止而終止。有時候,可能需要將對象的狀態(tài)保存下來,在需要時再將對象恢復(fù)。我們把對象的這種能記錄自己的狀態(tài) 以便將來再生的能力,叫做對象的持續(xù)性(persistence)。對象通過寫出描述自己狀態(tài)的數(shù)值來記錄自己,這個過程叫對象的串行化 (Serialization)。

  2. 串行化的目的

串行化的目的是為java的運(yùn)行環(huán)境提供一組特性,其主要任務(wù)是寫出對象實(shí)例變量的數(shù)值。

4.8.2 串行化方法

在java.io包中,接口Serializable用來作為實(shí)現(xiàn)對象串行化的工具,只有實(shí)現(xiàn)了Serializable的類的對象才可以被串行化。

 1. 定義一個可串行化對象

public class Student implements Serializable{
int id; //學(xué)號
String name; //姓名
int age; //年齡
String department //系別
public Student(int id,String name,int age,String department){
this.id = id;
this.name = name;
this.age = age;
this.department = department;
}
}

2. 構(gòu)造對象的輸入/輸出流

要串行化一個對象,必須與一定的對象輸入/輸出流聯(lián)系起來,通過對象輸出流將對象狀態(tài)保存下來,再通過對象輸入流將對象狀態(tài)恢復(fù)。

java.io包中,提供了ObjectInputStream和ObjectOutputStream將數(shù)據(jù)流功能擴(kuò)展至可讀寫對象。在 ObjectInputStream中用readObject()方法可以直接讀取一個對象,ObjectOutputStream中用 writeObject()方法可以直接將對象保存到輸出流中。

Student stu=new Student(981036,"Liu Ming",18, "CSD");
FileOutputStream fo=new FileOutputStream("data.ser");
//保存對象的狀態(tài)
ObjectOutputStream so=new ObjectOutputStream(fo);
try{
so.writeObject(stu);
so.close();
}catch(IOException e )
{System.out.println(e);}
FileInputStream fi=new FileInputStream("data.ser");
ObjectInputStream si=new ObjectInputStream(fi);
//恢復(fù)對象的狀態(tài)
try{
stu=(Student)si.readObject();
si.close();
}catch(IOException e )
{System.out.println(e);}

在 這個例子中,我們首先定義一個類Student,實(shí)現(xiàn)了 Serializable接口,然后通過對象輸出流的writeObject()方法將Student對象保存到文件data.ser中。之后,通過對象 輸入流的readObject()方法從文件data.ser中讀出保存下來的Student對象。

4.8.3 串行化的注意事項(xiàng)

 1.串行化能保存的元素

只能保存對象的非靜態(tài)成員變量,不能保存任何的成員方法和靜態(tài)的成員變量,而且串行化保存的只是變量的值,對于變量的任何修飾符,都不能保存。

2.transient關(guān)鍵字

對于某些類型的對象,其狀態(tài)是瞬時的,這樣的對象是無法保存其狀態(tài)的,例如一個Thread對象,或一個FileInputStream對象,對于這些字段,我們必須用transient關(guān)鍵字標(biāo)明

3. 定制串行化

缺省的串行化機(jī)制,對象串行化首先寫入類數(shù)據(jù)和類字段的信息,然后按照名稱的上升排列順序?qū)懭肫鋽?shù)值。如果想自己明確地控制這些數(shù)值的寫入順序和寫入 種類,必須定義自己的讀取數(shù)據(jù)流的方式。就是在類的定義中重寫writeObject()和readObject()方法。

例如可在4.8.2的例子中,加入重寫的writeObject()和readObject()方法,對Student 類定制其串行化。

private void writeObject(ObjectOutputStream out)throws IOException
{
out.writeInt(id);
out.writeInt(age);
out.writeUTF(name);
out.writeUTF(department);
}
private void readObject(ObjectInputStream in)throws IOException
{
id=in.readInt();
age=in.readInt();
name=in.readUTF();
department=in.readUTF();
}

補(bǔ)充日期: 2005-03-15 11:14:20

4.9 其它常用的流

4.9.1 管道流

  管道用來把一個程序、線程或代碼塊的輸出連接到另一個程序、線程或代碼塊的輸入 。

管道輸入流作為一個通信管道的接收端,管道輸出流作為發(fā)送端。在使用管道之前,管道輸出流和管道輸入流必須進(jìn)行連接。下面有兩種連接的方法:

1. 構(gòu)造方法中連接

PipedInputStream(PipedOutputStream src);
PipedOutputStream(PipedInputStream snk);

2. connect()方法進(jìn)行連接

類PipedInputStream中定義為:
void connect(PipedOutputStream src);
類PipedOutputStream中定義為:
void connect(PipedInputStream snk);

4.9.2 內(nèi)存的讀/寫

 1. ByteArrayInputStream和ByteArrayOutputStream

ByteArrayInputStream //從字節(jié)數(shù)組中讀取以字節(jié)為單位的數(shù)據(jù)
ByteArrayOutputStream //向字節(jié)數(shù)組中寫入以字節(jié)為單位的數(shù)據(jù)

2. StringBufferInputStream和StringBufferOutputStream

StringBufferInputStream
//從字符串緩沖區(qū)StringBuffer中讀取以字符為單位的數(shù)據(jù)

StringBufferOutputStream
//向字符串緩沖區(qū)StringBuffer中寫入以字符為單位的數(shù)據(jù)

4.9.3 順序輸入流

  SequenceInputStream 把幾個輸入流順序連接起來。順序輸入流提供了把若干不同的流統(tǒng)一為同一個流的功能,使得程序變得更加簡潔。

【本講小結(jié)】

  例外處理是java語言中一個獨(dú)特之處,主要使用捕獲例外和聲明拋棄例外兩種方法來處理程序中可能出現(xiàn)例外的語句塊,其中捕獲例外的方法是一種積極地處理例外的方法,而聲明拋棄例外是一種消極的處理例外的方法。

Java中的輸入/輸出處理是通過使用流技術(shù),用統(tǒng)一的接口表示而實(shí)現(xiàn)的。輸入/輸出流中,最常見的是對文件的處理。Java語言中提供專門處理文件 和目錄的類,例如:java.io.File,java.io.FileInputStream,java.io.FileOutputStream, java.io.RandomAccessFile和接口java.io.FilenameFilter。輸入/輸出流根據(jù)處理的內(nèi)容,分為字符流和字節(jié) 流兩種,其中字節(jié)流是以byte為基本處理單位的流;而字符流是以16位的Unicode碼為處理單位的流。

補(bǔ)充日期: 2005-03-30 09:56:05

java文件操作,再看

http://www.tiantiansoft.com/Article_Show.asp?ArticleID=163