`

InputStream 和OutputStream

 
阅读更多

1.InputStream 

◇ 从流中读取数据: 
int read( ); //读取一个字节,返回值为所读的字节 
int read( byte b[ ] ); //读取多个字节,放置到字节数组b中,通常读取的字节数量为b的长度,返回值为实际读取的字节的数量 
int read( byte b[ ], int off, int len ); //读取len个字节,放置到以下标off开始字节数组b中,返回值为实际读取的字节的数量 
int available( );   //返回值为流中尚未读取的字节的数量 
long skip( long n ); //读指针跳过n个字节不读,返回值为实际跳过的字节数量 

◇ 关闭流: 
close( ); //流操作完毕后必须关闭 

◇ 使用输入流中的标记: 
void mark( int readlimit ); //记录当前读指针所在位置,readlimit 表示读指针读出readlimit个字节后所标记的指针位置才失效 
void reset( );     //把读指针重新指向用mark方法所记录的位置 
boolean markSupported( ); //当前的流是否支持读指针的记录功能 

有关每个方法的使用,详见java API。 


2.OutputStream 

◇ 输出数据: 
void write( int b );   //往流中写一个字节b 
void write( byte b[ ] ); //往流中写一个字节数组b 
void write( byte b[ ], int off, int len ); //把字节数组b中从下标off开始,长度为len的字节写入流中 

◇ flush( )  //刷空输出流,并输出所有被缓存的字节,由于某些流支持缓存功能,该方法将把缓存中所有内容强制输出到流中。 

◇ 关闭流: 
close( );       //流操作完毕后必须关闭 


4.4.3 I/O中的例外 


  进行I/O操作时可能会产生I/O例外,属于非运行时例外,应该在程序中处理。如:FileNotFoundException, EOFException, IOException 


4.5 文件处理 

I/O处理中,最常见的是对文件的操作,java.io包中有关文件处理的类有:File、FileInputStream、 FileOutputStream、RamdomAccessFile和FileDescriptor;接口有:FilenameFilter。 

4.5.1 文件描述 

类File提供了一种与机器无关的方式来描述一个文件对象的属性。下面我们介绍类File中提供的各种方法。 


 ◇ 文件或目录的生成 

public File(String path);//如果path是实际存在的路径,则该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); //将当前文件名更名为给定文件的完整路径 

◇ 文件属性测试 

boolean exists( ); //测试当前File对象所指示的文件是否存在 
boolean canWrite( );//测试当前文件是否可写 
boolean canRead( );//测试当前文件是否可读 
boolean isFile( ); //测试当前文件是否是文件(不是目录) 
boolean isDirectory( ); //测试当前文件是否是目录 

◇ 普通文件信息和工具 

long lastModified( );//得到文件最近一次修改的时间 
long length( ); //得到文件的长度,以字节为单位 
boolean delete( ); //删除当前文件 

◇ 目录操作 

boolean mkdir( ); //根据当前对象生成一个由该对象指定的路径 
String list( ); //列出当前目录下的文件 

【例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 下的文件或目录 
创建一个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); //返回文件的后缀名 



4.5.2 文件的顺序处理 

类FileInputStream和FileOutputStream用来进行文件I/O处理,由它们所提供的方法可以打开本地主机上的文件,并进行 顺序的读/写。例如,下列的语句段是顺序读取文件名为text的文件里的内容,并显示在控制台上面,直到文件结束为止。 


FileInputStream fis; 
try{ 
fis = new FileInputStream( "text" ); 
System.out.print( "content of text is : "); 
int b; 
while( (b=fis.read())!=-1 ) //顺序读取文件text里的内容并赋值 
给整型变量b,直到文件结束为止。 
{               
System.out.print( (char)b ); 

}catch( FileNotFoundException e ){ 
System.out.println( e ); 
}catch( IOException e ){ 
System.out.println( e ); 



4.5.3 随机访问文件 

对于InputStream 和OutputStream 来说,它们的实例都是顺序访问流,也就是说,只能对文件进行顺序地读/写。随机访问文件则允许对文件内容进行随机读/写。在java中,类RandomAccessFile 提供了随机访问文件的方法。类RandomAccessFile的声明为: 
public class RandomAccessFile extends Object implements DataInput, DataOutput 


  接口DataInput 中定义的方法主要包括从流中读取基本类型的数据、读取一行数据、或者读取指定长度的字节数。如:readBoolean( )、readInt( )、readLine( )、readFully( ) 等。 

接口DataOutput 中定义的方法主要是向流中写入基本类型的数据、或者写入一定长度的字节数组。如:writeChar( )、writeDouble( )、write( ) 等。 下面详细介绍RandomAccessFile类中的方法。 

◇ 构造方法: 
RandomAccessFile(String name,String mode); //name是文件名,mode 
//是打开方式,例如"r"表示只读,"rw"表示可读写," 
RandomAccessFile(File file,String mode); //file是文件对象 

◇ 文件指针的操作 
long getFilePointer( ); //用于得到当前的文件指针 
void seek( long pos ); //用于移动文件指针到指定的位置 
int skipBytes( int n ); //使文件指针向前移动指定的n个字节 


4.6 过滤流 

过滤流在读/写数据的同时可以对数据进行处理,它提供了同步机制,使得某一时刻只有一个线程可以访问一个I/O流,以防止多个线程同时对一个I/O流进行 操作所带来的意想不到的结果。类FilterInputStream和FilterOutputStream分别作为所有过滤输入流和输出流的父类 


 过滤流类层次: 



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




为了使用一个过滤流,必须首先把过滤流连接到某个输入/出流上,通常通过在构造方法的参数中指定所要连接的输入/出流来实现。例如: 

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


4.6.1 几种常见的过滤流 


  ◇ BufferedInputStream和BufferedOutputStream 
缓冲流,用于提高输入/输出处理的效率。 

◇ DataInputStream 和 DataOutputStream 
不仅能读/写数据流,而且能读/写各种的java语言的基本类型,如:boolean,int,float等。 

◇ LineNumberInputStream 
除了提供对输入处理的支持外,LineNumberInputStream可以记录当前的行号。 

◇ PushbackInputStream 
提供了一个方法可以把刚读过的字节退回到输入流中,以便重新再读一遍。 

◇ PrintStream 
打印流的作用是把Java语言的内构类型以其字符表示形式送到相应的输出流。 


4.7 字符流的处理 

java中提供了处理以16位的Unicode码表示的字符流的类,即以Reader和Writer 为基类派生出的一系列类。 

4.7.1 Reader和Writer 


   这两个类是抽象类,只是提供了一系列用于字符流处理的接口,不能生成这两个类的实例,只能通过使用由它们派生出来的子类对象来处理字符流。 

1.Reader类是处理所有字符流输入类的父类。 

◇ 读取字符 
public int read() throws IOException; //读取一个字符,返回值为读取的字符 
public int read(char cbuf[]) throws IOException; /*读取一系列字符到数组cbuf[]中,返回值为实际读取的字符的数量*/ 
public abstract int read(char cbuf[],int off,int len) throws IOException; 
/*读取len个字符,从数组cbuf[]的下标off处开始存放,返回值为实际读取的字符数量,该方法必须由子类实现*/ 

◇ 标记流 
public boolean markSupported(); //判断当前流是否支持做标记 
public void mark(int readAheadLimit) throws IOException; 
//给当前流作标记,最多支持readAheadLimit个字符的回溯。 
public void reset() throws IOException; //将当前流重置到做标记处 

◇ 关闭流 
public abstract void close() throws IOException; 

2. Writer类是处理所有字符流输出类的父类。 

◇ 向输出流写入字符 
public void write(int c) throws IOException; 
//将整型值c的低16位写入输出流 
public void write(char cbuf[]) throws IOException; 
//将字符数组cbuf[]写入输出流 
public abstract void write(char cbuf[],int off,int len) throws IOException; 
//将字符数组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( ) 
刷空输出流,并输出所有被缓存的字节。 

◇ 关闭流 
public abstract void close() throws IOException; 


4.7.2 InputStreamReader和OutputStreamWriter 

java.io包中用于处理字符流的最基本的类,用来在字节流和字符流之间作为中介。 
  ◇ 生成流对象 
  public InputStreamReader(InputStream in); 
/*in是字节流,而InputStreamReader是字符流,但是其来源是字节流in, 
因此InputStreamReader就可以把字节流in转换成字符流处理。/* 

public InputStreamReader(InputStream in,String enc) throws UnsupportedEncodingException; 
/*enc是编码方式,就是从字节流到字符流进行转换时所采用的编码方式, 
例如 ISO8859-1,UTF-8,UTF-16等等*/ 

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

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

InputStreamReader和OutputStreamWriter的方法: 

◇ 读入和写出字符 
基本同Reader和Writer。 

◇ 获取当前编码方式 
public String getEncoding(); 

◇ 关闭流 
public void close() throws IOException; 


4.7.3 BufferedReader和BufferedWriter 


 ◇ 生成流对象 

public BufferedReader(Reader in); //使用缺省的缓冲区大小 
public BufferedReader(Reader in, int sz); //sz为缓冲区的大小 
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); 
//从键盘接收了一个字符串的输入,并创建了一个字符输入流的对象 
in=new BufferedReader(ir); 
String s=in.readLine(); 
//从输入流in中读入一行,并将读取的值赋值给字符串变量s 
System.out.println("Input value is: "+s); 
int i = Integer.parseInt(s);//转换成int型 
i*=2; 
System.out.println("Input value changed after doubled: "+i); 
}catch(IOException e) 
{System.out.println(e);} 



运行结果 


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



注意:在读取字符流时,如果不是来自于本地的,比如说来自于网络上某处的与本地编码方式不同的机器,那么我们在构造输入流时就不能简单地使用本地缺省的编码方式,否则读出的字符就不正确;为了正确地读出异种机上的字符,我们应该使用下述方式构造输入流对象: 

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

采用ISO 8859_1编码方式,这是一种映射到ASCII码的编码方式,可以在不同平台之间正确转换字符。 



4.8 对象的串行化(Serialization) 


4.8.1 串行化的定义 


  1. 什么是串行化 

对象的寿命通常随着生成该对象的程序的终止而终止。有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复。我们把对象的这种能记录自己的状态 以便将来再生的能力,叫做对象的持续性(persistence)。对象通过写出描述自己状态的数值来记录自己,这个过程叫对象的串行化 (Serialization)。 


  2. 串行化的目的 

串行化的目的是为java的运行环境提供一组特性,其主要任务是写出对象实例变量的数值。 


4.8.2 串行化方法 

在java.io包中,接口Serializable用来作为实现对象串行化的工具,只有实现了Serializable的类的对象才可以被串行化。 


 1. 定义一个可串行化对象 

public class Student implements Serializable{ 
int id; //学号 
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. 构造对象的输入/输出流 

要串行化一个对象,必须与一定的对象输入/输出流联系起来,通过对象输出流将对象状态保存下来,再通过对象输入流将对象状态恢复。 

java.io包中,提供了ObjectInputStream和ObjectOutputStream将数据流功能扩展至可读写对象。在 ObjectInputStream中用readObject()方法可以直接读取一个对象,ObjectOutputStream中用 writeObject()方法可以直接将对象保存到输出流中。 

Student stu=new Student(981036,"Liu Ming",18, "CSD"); 
FileOutputStream fo=new FileOutputStream("data.ser"); 
//保存对象的状态 
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); 
//恢复对象的状态 
try{ 
stu=(Student)si.readObject(); 
si.close(); 
}catch(IOException e ) 
{System.out.println(e);} 

在 这个例子中,我们首先定义一个类Student,实现了 Serializable接口,然后通过对象输出流的writeObject()方法将Student对象保存到文件data.ser中。之后,通过对象 输入流的readObject()方法从文件data.ser中读出保存下来的Student对象。 


4.8.3 串行化的注意事项 


 1.串行化能保存的元素 

只能保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量,而且串行化保存的只是变量的值,对于变量的任何修饰符,都不能保存。 

2.transient关键字 

对于某些类型的对象,其状态是瞬时的,这样的对象是无法保存其状态的,例如一个Thread对象,或一个FileInputStream对象,对于这些字段,我们必须用transient关键字标明 

3. 定制串行化 

缺省的串行化机制,对象串行化首先写入类数据和类字段的信息,然后按照名称的上升排列顺序写入其数值。如果想自己明确地控制这些数值的写入顺序和写入 种类,必须定义自己的读取数据流的方式。就是在类的定义中重写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(); 



4.9 其它常用的流 

4.9.1 管道流 


  管道用来把一个程序、线程或代码块的输出连接到另一个程序、线程或代码块的输入 。 

管道输入流作为一个通信管道的接收端,管道输出流作为发送端。在使用管道之前,管道输出流和管道输入流必须进行连接。下面有两种连接的方法: 

1. 构造方法中连接 

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

2. connect()方法进行连接 

类PipedInputStream中定义为: 
void connect(PipedOutputStream src); 
类PipedOutputStream中定义为: 
void connect(PipedInputStream snk); 


4.9.2 内存的读/写 


 1. ByteArrayInputStream和ByteArrayOutputStream 

ByteArrayInputStream //从字节数组中读取以字节为单位的数据 
ByteArrayOutputStream //向字节数组中写入以字节为单位的数据 

2. StringBufferInputStream和StringBufferOutputStream 

StringBufferInputStream 
//从字符串缓冲区StringBuffer中读取以字符为单位的数据 
StringBufferOutputStream 
//向字符串缓冲区StringBuffer中写入以字符为单位的数据 


4.9.3 顺序输入流 


  SequenceInputStream 把几个输入流顺序连接起来。顺序输入流提供了把若干不同的流统一为同一个流的功能,使得程序变得更加简洁。 


【本讲小结】 

  例外处理是java语言中一个独特之处,主要使用捕获例外和声明抛弃例外两种方法来处理程序中可能出现例外的语句块,其中捕获例外的方法是一种积极地处理例外的方法,而声明抛弃例外是一种消极的处理例外的方法。 

Java中的输入/输出处理是通过使用流技术,用统一的接口表示而实现的。输入/输出流中,最常见的是对文件的处理。Java语言中提供专门处理文件 和目录的类,例如:java.io.File,java.io.FileInputStream,java.io.FileOutputStream, java.io.RandomAccessFile和接口java.io.FilenameFilter。输入/输出流根据处理的内容,分为字符流和字节 流两种,其中字节流是以byte为基本处理单位的流;而字符流是以16位的Unicode码为处理单位的流。

 

以下是一个读取一个文件,并把写到指定的文件中:

String dataseFileName = "sdcard/region.db"; 
    		if (!(new File(dataseFileName)).exists()) {
    			InputStream is = getContext().getResources().getAssets().open("region.db");
// assets目录下有一个region数据库文件
    			FileOutputStream fos = new FileOutputStream(dataseFileName);
    			byte[] buff = new byte[8192];
    			int count = 0;
    			while ((count = is.read(buff)) > 0){
    				fos.write(buff,0,count);
    			}
    			fos.close();
    			is.close();
    		}

 

 

 

来自:http://blog.csdn.net/dww410/article/details/5399094

分享到:
评论

相关推荐

    关于InputStream和OutputStream详细讲解

    关于InputStream和OutputStream关于InputStream和OutputStream关于InputStream和OutputStream关于InputStream和OutputStream

    InputStream与OutputStream及File间互转

    在Java编程语言中,`InputStream`和`OutputStream`是处理数据流的核心类,它们属于Java的I/O(Input/Output)框架。`File`类则用于处理文件操作,如读写、创建、删除等。理解如何在这些对象之间进行转换是Java开发中...

    IO流文档InputStream / OutputStream

    IO流是Java中的一种基本的数据交换方式,通过InputStream和OutputStream可以实现数据的读取和写入,而Reader和Writer可以实现字符流的读取和写入。IO流的知识点很多,需要认真学习和掌握。 InputStream的类型: * ...

    java-0126递归&过滤器(listFiter)&InputStream&OutputStream

    InputStream 和 OutputStream InputStream 是一种输入流,用于读取数据。InputStream 可以用来读取文件、网络数据等。 OutputStream 是一种输出流,用于写入数据。OutputStream 可以用来写入文件、网络数据等。 ...

    Java基础核心+InputStream输入流+OutputStream输出流

    本教程将聚焦于Java的基础核心,以及两个重要的I/O(输入/输出)流类——InputStream和OutputStream,它们在文件操作中扮演着关键角色。 InputStream和OutputStream是Java.io包下的抽象类,是所有字节流的基类。...

    将输出流OutputStream转化为输入流InputStream的方法

    首先,我们需要理解`OutputStream`和`InputStream`这两个核心的I/O类。`OutputStream`是用于写出数据到目的地的流,而`InputStream`则是用于读取数据的流。在Java中,它们是Java.io包下的基础类,提供了多种子类来...

    java_io.doc

    1. **InputStream 和 OutputStream**: 这是Java I/O的基础,分别代表了数据的输入和输出。InputStream用于读取原始字节流,而OutputStream用于写入原始字节流。例如,FileInputStream和FileOutputStream分别用于从...

    IO流体系继承结构图_动力节点Java学院整理

    InputStream和OutputStream是抽象类,它们提供了基本的读写操作,如read()和write()方法。原始处理器(适配器)是用来将不同类型的输入/输出资源转换为InputStream或OutputStream的类。例如,ByteArrayInputStream...

    java io InputStream and outputStream

    InputStream is = new FileInputStream(file1);// 打开文件 byte[] cont = new byte[(int) file1.length()]; is.read(cont);// 读取文件 for (int i = 0; i ; i++) { System.out.print((char) ...

    JAVA语言SOCKET机制的研究.pdf

    2. 获取Socket的InputStream和OutputStream,用于读写数据。 3. 通过InputStream读取服务器返回的数据,OutputStream用于向服务器发送数据。 4. 当通信完成后,关闭Socket、InputStream和OutputStream。 对于服务器...

    Android经典设计源码-IOStreamSample.rar

    《Android经典设计源码-IOStreamSample》是一个深入解析Android平台下I/O流(InputStream和OutputStream)使用的设计实例。在Android开发中,I/O流是处理数据输入输出的基础工具,对于任何涉及文件读写、网络通信的...

    Java编程中多种IO API复制文件的性能分析.pdf

    流式IO是Java中最基本的IO操作方式,通过InputStream和OutputStream来实现输入输出操作。InputStream用于读取数据,而OutputStream用于写出数据。Java中的流式IO可以分为两种:字节流和字符流。字节流以字节为单位...

    java_io.pdf

    这一章主要讲解了Java中的I/O流,包括InputStream、OutputStream、Reader和Writer类的使用及其相关的子类。下面将详细阐述这些知识点。 1. **InputStream与OutputStream**: - **InputStream**:这是所有字节输入...

    轻松学Java之Java的输入输出流优秀PPT.pptx

    其中InputStream和OutputStream表示字节流,Reader和Writer表示字符流,其他流均是继承这四个抽象类而来的。 在Java中,输入输出流的处理是通过java.io包中的类来实现的。java.io包提供了多种类来处理输入输出流,...

    java socket通信实现

    3. InputStream和OutputStream:Socket提供的InputStream和OutputStream是处理数据传输的基础。服务端和客户端可以通过这些流对象读写数据,实现双方的数据交换。 三、服务端实现 服务端程序主要包含以下步骤: 1. ...

    JAVA文件传输(论文+源代码).rar

    字节流的基类是InputStream和OutputStream,字符流的基类是Reader和Writer。此外,还有缓冲流(BufferedInputStream/BufferedReader)、转换流(InputStreamReader/OutputStreamWriter)和对象流(ObjectInputStream...

    Java中的字节流文件读取教程(一)

    OutputStream和InputStream是类似的,只不过一个是写一个是读。他们都有相似的方法,如write方法和read方法。 6. FileInputStream和FileOutputStream FileInputStream和FileOutputStream是字节流的实现类,分别...

    Socket案例源码

    在Java中,Socket类代表了服务器和客户端之间的连接,InputStream和OutputStream则分别用于读写数据。本案例中,我们可能会看到ServerSocket用于服务器端监听客户端连接,而Socket对象用于客户端与服务器建立连接。 ...

    软件工程师-浅谈Java的输入输出流技术步骤说明.pdf

    Reader 和 Writer 是基于字符流的,它们是后来加入的,以补充 InputStream 和 OutputStream。 InputStream 和 Reader 定义了完全相同的接口: * int read() * int read(char cbuf[]) * int read(char cbuf[], int ...

    Java远程监控系统设计及功能介绍.doc

    Java远程监控系统设计涉及多个核心组件和技术,包括Socket通信、InputStream和OutputStream数据传输、Robot对象的屏幕截图以及UDP协议的使用。以下是对这些知识点的详细解释: 1. **Socket通信**: Java中的Socket...

Global site tag (gtag.js) - Google Analytics