java io详解 2.docx

上传人:b****8 文档编号:10963003 上传时间:2023-02-24 格式:DOCX 页数:24 大小:169.89KB
下载 相关 举报
java io详解 2.docx_第1页
第1页 / 共24页
java io详解 2.docx_第2页
第2页 / 共24页
java io详解 2.docx_第3页
第3页 / 共24页
java io详解 2.docx_第4页
第4页 / 共24页
java io详解 2.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

java io详解 2.docx

《java io详解 2.docx》由会员分享,可在线阅读,更多相关《java io详解 2.docx(24页珍藏版)》请在冰豆网上搜索。

java io详解 2.docx

javaio详解2

javaio详解

什么是IO 

IO(Input/Output)是计算机输出/输出的接口。

Java的核心库java.io提供了全面的IO接口,包括:

文件读写,标准设备输出等等。

Java中IO是以流为基础进行输入输出的,所有数据被串行化写入输出流,或者从输入流读入。

此外,Java也对块传输提供支持,在核心库java.nio中采用的便是块IO。

关于NIO我们在后面还有专门的讨论。

 

  流IO的好处是简单易用,缺点是效率较低。

块IO效率很高,但编程比较复杂。

 

Java IO模型

Java的IO模型设计非常优秀,它使用Decorator模式,按功能划分Stream,您可以动态装配这些Stream,以便获得您需要的功能。

例如,您需要一个具有缓冲的文件输入流,则应当组合使用FileInputStream和BufferedInputStream。

 

  Java的IO体系分Input/Output和Reader/Writer两类,区别在于Reader/Writer在读写文本时能自动转换内码。

基本上,所有的IO类都是配对的,即有XxxInput就有一个对应的XxxOutput。

 

Java IO教程

如果您对Decorator模式非常了解,就能轻易地看出Java的IO类结构:

根接口是InputStream/OutputStream,充当数据源的IO类有FileInputStream/FileOutputStream,ByteArrayInputStream/ByteArrayOutputStream等,充当装饰功能的IO类有BufferedInputStream/BufferedOutputStream,DataInputStream/DataOutputStream等,它们都是继承装饰接口FilterInputStream/FilterOutputStream。

使用IO时,首先创建一个数据源IO,然后根据需要的功能创建装饰类IO,其构造函数的参数为已创建的数据源IO。

我们以创建一个具有缓冲的文件输入流为例,假定需要从磁盘读取文件“C:

\log.txt”:

// 创建一个FileInputStream:

 

FileInputStream fileInput = new FileInputStream("C:

\\log.txt"); 

// 创建一个BufferedInputStream:

 

BufferedInputStream bufferedInput = new BufferedInputStream(fileInput);  

// 现在得到的bufferedInput即是具有缓冲的文件输入流或者进一步简写如下:

InputStream input = new BufferedInputStream( new FileInputStream("C:

\\log.txt"));

// 现在得到的input即是具有缓冲的文件输入流

在您对Java的IO有了总体了解后,我们推荐您看看教程Introduction to Java I/O和I/O:

 Reading and Writing。

浅谈java输入输出流

一.字符流与字节流的区别:

 

  Java流在处理上分为字符流和字节流。

字符流处理的单元为2个字节的Unicode字符,分别操作字符、字符数组或字符串,而字节流处理单元为1个字节,操作字节和字节数组。

Java内用Unicode编码存储字符,字符流处理类负责将外部的其他编码的字符流和java内Unicode字符流之间的转换。

而类InputStreamReader和OutputStreamWriter处理字符流和字节流的转换。

字符流(一次可以处理一个缓冲区)一次操作比字节流(一次一个字节)效率高。

(一)以字节为导向的stream(InputStream/OutputStream)

InputStream和OutputStream是两个abstact类,对于字节为导向的stream都扩展这两个鸡肋(基类^_^);

1、InputStream

1.1ByteArrayInputStream:

把内存中的一个缓冲区作为InputStream使用.

(A)---ByteArrayInputStream(byte[])创建一个新字节数组输入流(ByteArrayInputStream),它从指定字节数组中读取数据(使用byte作为其缓冲区数组)

(B)---ByteArrayInputStream(byte[],int,int)创建一个新字节数组输入流,它从指定字节数组中读取数据。

注:

该字节数组未被复制。

1.2StringBufferInputStream:

把一个String对象作为InputStream.

StringBufferInputStream(String)据指定串创建一个读取数据的输入流串。

注释:

不推荐使用StringBufferInputStream方法。

此类不能将字符正确的转换为字节。

同JDK1.1版中的类似,从一个串创建一个流的最佳方法是采用StringReader类。

1.3FileInputStream:

把一个文件作为InputStream,实现对文件的读取操作

(A)---FileInputStream(Filename)创建一个输入文件流,从指定的File对象读取数据。

(B)---FileInputStream(FileDescriptor)创建一个输入文件流,从指定的文件描述器读取数据。

(C)---FileInputStream(Stringname)创建一个输入文件流,从指定名称的文件读取数据。

方法:

read()从当前输入流中读取一字节数据。

read(byte[])将当前输入流中b.length个字节数据读到一个字节数组中。

read(byte[],int,int)将输入流中len个字节数据读入一个字节数组中。

1.4PipedInputStream:

实现了pipe的概念,主要在线程中使用.管道输入流是指一个通讯管道的接收端。

一个线程通过管道输出流发送数据,而另一个线程通过管道输入流读取数据,这样可实现两个线程间的通讯。

PipedInputStream()创建一个管道输入流,它还未与一个管道输出流连接。

PipedInputStream(PipedOutputStream)创建一个管道输入流,它已连接到一个管道输出流。

1.5SequenceInputStream:

把多个InputStream合并为一个InputStream.“序列输入流”类允许应用程序把几个输入流连续地合并起来,并且使它们像单个输入流一样出现。

每个输入流依次被读取,直到到达该流的末尾。

然后“序列输入流”类关闭这个流并自动地切换到下一个输入流。

SequenceInputStream(Enumeration)创建一个新的序列输入流,并用指定的输入流的枚举值初始化它。

SequenceInputStream(InputStream,InputStream)创建一个新的序列输入流,初始化为首先读输入流s1,然后读输入流s2。

2、OutputSteam

 

2.1ByteArrayOutputStream:

把信息存入内存中的一个缓冲区中.该类实现一个以字节数组形式写入数据的输出流。

当数据写入缓冲区时,它自动扩大。

用toByteArray()和toString()能检索数据。

(A)---ByteArrayOutputStream()创建一个新的字节数组输出流。

(B)---ByteArrayOutputStream()创建一个新的字节数组输出流。

(C)---ByteArrayOutputStream(int)创建一个新的字节数组输出流,并带有指定大小字节的缓冲区容量。

toString(String)根据指定字符编码将缓冲区内容转换为字符串,并将字节转换为字符。

write(byte[],int,int)将指定字节数组中从偏移量off开始的len个字节写入该字节数组输出流。

write(int)将指定字节写入该字节数组输出流。

writeTo(OutputStream)用out.write(buf,0,count)调用输出流的写方法将该字节数组输出流的全部内容写入指定的输出流参数。

2.2  FileOutputStream:

文件输出流是向File或FileDescriptor输出数据的一个输出流。

(A)---FileOutputStream(Filename)创建一个文件输出流,向指定的File对象输出数据。

(B)---FileOutputStream(FileDescriptor)创建一个文件输出流,向指定的文件描述器输出数据。

(C)---FileOutputStream(Stringname)创建一个文件输出流,向指定名称的文件输出数据。

(D)---FileOutputStream(String,boolean)用指定系统的文件名,创建一个输出文件。

2.3PipedOutputStream:

管道输出流是指一个通讯管道的发送端。

一个线程通过管道输出流发送数据,

而另一个线程通过管道输入流读取数据,这样可实现两个线程间的通讯。

(A)---PipedOutputStream()创建一个管道输出流,它还未与一个管道输入流连接。

(B)---PipedOutputStream(PipedInputStream)创建一个管道输出流,它已连接到一个管道输入流。

(二)以字符为导向的streamReader/Writer

以Unicode字符为导向的stream,表示以Unicode字符为单位从stream中读取或往stream中写入信息。

Reader/Writer为abstact类,以Unicode字符为导向的stream包括下面几种类型:

1.Reader

1.1CharArrayReader:

与ByteArrayInputStream对应此类实现一个可用作字符输入流的字符缓冲区

CharArrayReader(char[])用指定字符数组创建一个CharArrayReader。

CharArrayReader(char[],int,int)用指定字符数组创建一个CharArrayReader

1.2StringReader:

与StringBufferInputStream对应其源为一个字符串的字符流。

StringReader(String)创建一新的串读取者。

1.3FileReader:

与FileInputStream对应

1.4PipedReader:

与PipedInputStream对应

 

2.Writer

2.1CharArrayWrite:

与ByteArrayOutputStream对应

2.2 StringWrite:

无与之对应的以字节为导向的stream

2.3FileWrite:

与FileOutputStream对应

2.4PipedWrite:

与PipedOutputStream对应

以字符为导向的stream基本上有与之相对应的以字节为导向的stream。

两个对应类实现的功能相同,只是在操作时的导向不同。

如CharArrayReader:

和ByteArrayInputStream的作用都是把内存中的一个缓冲区作为InputStream使用,所不同的是前者每次从内存中读取一个字节的信息,而后者每次从内存中读取一个字符。

   Reader和Writer要解决的,最主要的问题就是国际化。

原先的I/O类库只支持8位的字节流,因此不可能很好地处理16位的Unicode字符流。

Unicode是国际化的字符集(更何况Java内置的char就是16位的Unicode字符),这样加了Reader和Writer之后,所有的I/O就都支持Unicode了。

此外新类库的性能也比旧的好。

 

  但是,Read和Write并不是取代InputStream和OutputStream,有时,你还必须同时使用"基于byte的类"和"基于字符的类"。

为此,它还提供了两个"适配器(adapter)"类。

InputStreamReader负责将InputStream转化成Reader,而OutputStreamWriter则将OutputStream转化成Writer。

3、两种不同导向的stream之间的转换  

3.1InputStreamReader和OutputStreamReader:

把一个以字节为导向的stream转换成一个以字符为导向的stream。

InputStreamReader类是从字节流到字符流的桥梁:

它读入字节,并根据指定的编码方式,将之转换为字符流。

使用的编码方式可能由名称指定,或平台可接受的缺省编码方式。

InputStreamReader的read()方法之一的每次调用,可能促使从基本字节输入流中读取一个或多个字节。

为了达到更高效率,考虑用BufferedReader封装InputStreamReader,

BufferedReaderin=newBufferedReader(newInputStreamReader(System.in));

例如:

//实现从键盘输入一个整数

viewplaincopytoclipboardprint?

Strings= null;             

InputStreamReaderre= new InputStreamReader(System.in);  

BufferedReaderbr= new BufferedReader(re);  

try {  

        s=br.readLine();  

        System.out.println("s=" +Integer.parseInt(s));  

        br.close();  

}   catch (IOExceptione)  {  

        e.printStackTrace();

//当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。

   

} catch (NumberFormatExceptione) {  

        System.out.println("输入的不是数字");  

}  

InputStreamReader(InputStream)用缺省的字符编码方式,创建一个InputStreamReader。

InputStreamReader(InputStream,String)用已命名的字符编码方式,创建一个InputStreamReader。

OutputStreamWriter将多个字符写入到一个输出流,根据指定的字符编码将多个字符转换为字节。

每个OutputStreamWriter合并它自己的CharToByteConverter,因而是从字符流到字节流的桥梁。

2、stream添加属性

2.1“为stream添加属性”的作用

运用上面介绍的Java中操作IO的API,我们就可完成我们想完成的任何操作了。

但通过FilterInputStream和FilterOutStream的子类,我们可以为stream添加属性。

下面以一个例子来说明这种功能的作用。

如果我们要往一个文件中写入数据,我们可以这样操作:

FileOutStreamfs=newFileOutStream(“test.txt”);

然后就可以通过产生的fs对象调用write()函数来往test.txt文件中写入数据了。

但是,如果我们想实现“先把要写入文件的数据先缓存到内存中,再把缓存中的数据写入文件中”的功能时,上面的API就没有一个能满足我们的需求了。

但是通过FilterInputStream和FilterOutStream的子类,为FileOutStream添加我们所需要的功能。

2.2FilterInputStream的各种类型

2.2.1用于封装以字节为导向的InputStream

1)DataInputStream:

从stream中读取基本类型(int、char等)数据。

2)BufferedInputStream:

使用缓冲区

3)LineNumberInputStream:

会记录inputstream内的行数,然后可以调用getLineNumber()和setLineNumber(int)

4)PushbackInputStream:

很少用到,一般用于编译器开发

2.2.2用于封装以字符为导向的InputStream

1)没有与DataInputStream对应的类。

除非在要使用readLine()时改用BufferedReader,否则使用DataInputStream

2)BufferedReader:

与BufferedInputStream对应

3)LineNumberReader:

与LineNumberInputStream对应

4)PushBackReader:

与PushbackInputStream对应

2.3FilterOutStream的各种类型

2.2.3用于封装以字节为导向的OutputStream

1)DataIOutStream:

往stream中输出基本类型(int、char等)数据。

2)BufferedOutStream:

使用缓冲区

3)PrintStream:

产生格式化输出

2.2.4用于封装以字符为导向的OutputStream

1)BufferedWrite:

与对应

2)PrintWrite:

与对应

3.RandomAccessFile

1)可通过RandomAccessFile对象完成对文件的读写操作

2)在产生一个对象时,可指明要打开的文件的性质:

r,只读;w,只写;rw可读写

3)可以直接跳到文件中指定的位置

二.流的层次结构 

  定义:

 

  

(1)java将读取数据对象成为输入流,能向其写入的对象叫输出流。

结构图如下:

输入流:

 

  

 

   

 

输出流 

  

 

三.InputStream类 

  inputstream类和outputstream类都为抽象类,不能创建对象,可以通过子类来实例化。

 

  InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法.Inputstream类中的常用方法:

 

  

(1)publicabstractintread():

读取一个byte的数据,返回值是高位补0的int类型值。

 

(2)publicintread(byteb[]):

读取b.length个字节的数据放到b数组中。

返回值是读取的字节数。

该方法实际上是调用下一个方法实现的 

(3)publicintread(byteb[],intoff,intlen):

从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。

 

(4)publicintavailable():

返回输入流中可以读取的字节数。

注意:

若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用, 

(5)publiclongskip(longn):

忽略输入流中的n个字节,返回值是实际忽略的字节数,跳过一些字节来读取

(6)publicintclose():

我们在使用完后,必须对我们打开的流进行关闭. 

四.OutputStream类 

  OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。

 

1.publicvoidwrite(byteb[]):

将参数b中的字节写到输出流。

 

  2.publicvoidwrite(byteb[],intoff,intlen):

将参数b的从偏移量off开始的len个字节写到输出流。

 

  3.publicabstractvoidwrite(intb):

先将int转换为byte类型,把低字节写入到输出流中。

 

  4.publicvoidflush():

将数据缓冲区中数据全部输出,并清空缓冲区。

 

  5.publicvoidclose():

关闭输出流并释放与流相关的系统资源。

 

   

  注意:

 

  1.上述各方法都有可能引起异常。

 

  2.InputStream和OutputStream都是抽象类,不能创建这种类型的对象。

 

五.FileInputStream类 

  FileInputStream类是InputStream类的子类,用来处理以文件作为数据输入源的数据流。

使用方法:

 

  方式1:

 

  Filefin=newFile("d:

/abc.txt"); 

  FileInputStreamin=newFileInputStream(fin); 

  方式2:

 

  FileInputStreamin=new 

  FileInputStream("d:

/abc.txt"); 

  方式3:

 

  构造函数将FileDescriptor()对象作为其参数。

 

  FileDescriptor()fd=newFileDescriptor(); 

  FileInputStreamf2=newFileInputStream(fd); 

   

六.FileOutputStream类 

  FileOutputStream类用来处理以文件作为数据输出目的数据流;一个表示文件名的字符串,也可以是File或FileDescriptor对象。

 

  创建一个文件流对象有两种方法:

 

  方式1:

 

  Filef=newFile("d:

/abc.txt"); 

  FileOutputStreamout=newFileOutputStream(f); 

  方式2:

 

  FileOutputStreamout=new 

  FileOutputStream("d:

/abc.txt"); 

  方式3:

构造函数将FileDescriptor()对象作为其参数。

 

  FileDescriptor()fd=newFileDescriptor(); 

  FileOutputStreamf2=newFileOutputStream(fd); 

  方式4:

构造函数将文件

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 经济学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1