`

Java 输入输出流详解

阅读更多

   最近一段时间,处于失业状态,正好有机会对未理解的知识进行整理,面试中这部分的知识很大可能也是会遇到的。下面的内容一部分是从网上筛选的,经过自己的梳理后总结的。

 

Java IO 用的是‘decorator模式’来构建的。要容易理解Java IO 应该从对称性和两个模式(装饰器模式和适配器模式)这两方面进行分析。

 

装饰器模式:

    在由InputStream、OutputStream、Reader和Writer 代表的等级结构内部,有一些流处理器可以对另外一些流处理器起到装饰作用,形成新的、具有改善了的功能的流处理器。

 

下面是Decorator模式的结构图:



1.Component就是装饰器模式中公共方法的类,在装饰器模式结构图的顶层。

2.ConcreateComponent是转换器模式中具体的被装饰的类,IO包中的媒体流就是此种对象。

3.Decorator装饰器模式中的核心对象,所有具体装饰器对象的父类,完成装饰器的部分职能。在上面的例子中Decorator类和这里的对应。该类可以只做一些简单的包裹被装饰的对象,也可以还包含对Component中方法的实现……他有一个鲜明的特点:继承至Component,同时包含一个Component作为其成员变量。装饰器模式动机中的动态地增加功能是在这里实现的。

4.ConcreteDecoratorA和ConcreteDecoratorB是两个具体的装饰器对象,他们完成具体的装饰功能。装饰功能的实现是通过调用被装饰对象对应的方法,加上装饰对象自身的方法。这是装饰器模式动机中的添加额外功能的关键。

 

装饰器模式相关知识参考http://miaoxiaodong78.blog.163.com/blog/static/18765136200701232434996/

 

适配器模式:

  将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 比如ByteArrayInputStream 是一个适配器类,它继承了InputStream,而封装了一个byte数组,换句话说,它将以个byte数组的接口适配成InputStream流处理器的接口。

适配器的结构图:



 

适配器相关的知识参考:http://www.cnblogs.com/houleixx/archive/2008/03/04/1090214.html

 

下面开始了解Java IO

   Java IO 中的流从不同的角度可以分成三类:
1、按数据流的方向不同可以分为输入流(InputStream/Reader)和输出流(OutputStream/Writer),用户可以从输入流中读取信息,但不能写它。相反,对输出流,只能往往输出流写,而不能读取。
2、按处理数据单位不同可以分为字节流(InputStream/OutputStream-8位)和字符流(Reader/Writer-16位)。
3、按功能不同可以分为节点流(原始流)和处理流(链接流)。节点流为可以从一个特定的数据源(节点)读写数据(如文件、内存)。处理流是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。

下面的分析是从功能上来分析的:

 

字节流处理类概述:

 

对于字节流处理的类都继承自InputStream和OutputStream这两个抽象类。

 

InputStream

 

InputStream结构图,从图中可以很清楚的看到装饰器模式的应用。



 

InputStream提供的最重要的方法是:

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

 

用于从输入流中读取字节。

 

原始流(也是一个适配器类):
(1)ByteArrayInputStream:为多线程的通信提供缓冲区操作,接收一个Byte数据作为流的源。


(2)FileInputStream:建立一个与文件有关的输入流。接收一个File对象作为流的源。


(3)PipedInputStream:可以与PipedOutputStream配合使用,用于读入一个数据管道的数据,接收一个PipedOutputStream 作为源。


(4)StringBufferInputStream:将一个字符串缓冲区转换为一个输入流。接收一个String对象作为流的源。


链接流:
(1)FilterInputStream称为过滤输入流,它将另外一个输入流作为流源。这个类的子类包括一下几种。
   BufferedInputStream: 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。在创建BufferedInputStream 时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。mark 操作记录输入流中的某个点,reset 操作使得在从包含的输入流中获取新字节之前,再次读取自最后一次 mark 操作后读取的所有字节。
   DataInputStream:数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用数据输出流写入稍后由数据输入流读取的数据。
   LineNumberInputStream(已过时):提供带有行计数功能的过滤输入流。
   PushbackInputStream:提供特殊的功能,可以将已经读取的字节“推回”到输入流中。


(2)ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化


(3)SequenceInputStream 表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

 

 

从结构图中可以看出直接引用InputStream(相当于装饰器模式中的Component) 的类就是链接流了。而FilterInputStream 相当于装饰器模式中的Decorator。以下的也是一样,所以就不一一分析了,其类的功能可查看API 文档。


 OutputStream(和InputStream相对应)

OutputStream结构图:

 

 

 

 

OutputStream提供的最重要的方法是:

write(int b);
write(byte[] b);
write(byte[] b, int off, int len) 

 用于将字节写入输出流。

 

 

 

字符流处理概述:

 

所有的字符流操作类都继承自Reader或者Writer这两个抽象类。

 

Reader

 

Reader结构图:



 

Reader提供的重要方法有:

read(char[] cbuf);
read(char[] cbuf, int off, int len);
read(CharBuffer target);

他们提供了从流中读取数据到字符数组或者CharBuffer的功能。

 

Writer

 

Writer结构图:



 

 

Writer提供的重要方法有:

write(char[] cbuf);
write(char[] cbuf, int off, int len);
write(int c);
write(String str);
write(String str, int off, int len);

 

他们提供了把字符、字符数组或者字符串写入流中的功能。

 

 

 

 字节流和字符流之间的转换(从字节流适配到字符流)


InputStreamReader和OutputStreamReader:把一个以字节为导向的stream转换成一个以字符为导向的stream。
InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集 。


OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

 

RandomAccessFile

RandomAccessFile:此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。

 

I/O应用的例子

 

package JavaIO;

import java.io.*;

public class JavaIO{
	public static void main(String[] args) throws Exception {
		// 1b. 接收键盘的输入
		/*
		 * 由于想以缓存字节读取方式从标准IO(键盘)中读取数据,所以要
		 * 先把标准IO(System.in)转换成字符导向的stream,再进行BufferedReader封装。
		 */
		BufferedReader stdin = new BufferedReader(new InputStreamReader(
				System.in));
		System.out.println("Enter a line:");
		System.out.println(stdin.readLine());

		// 2. 从一个String对象中读取数据
		/*
		 * 要以字符的形式从一个String对象中读取数据,所以要产生一个StringReader类型的stream。
		 */
		StringReader in2 = new StringReader("zhxing");
		int c;
		while ((c = in2.read()) != -1)
			System.out.println((char) c);
		in2.close();

		// 3. 从内存取出格式化输入
		// 把内存中的一个缓冲区作为DataInputStream使用
		try {
			DataInputStream in3 = new DataInputStream(new ByteArrayInputStream(
					"zhxing".getBytes()));
			while (true)
				System.out.println((char) in3.readByte());
		} catch (EOFException e) {
			System.out.println("End of stream");
		}

		// 4. 输出到文件
		/*
		 * 对String对象s2读取数据时,先把对象中的数据存入缓存中,再从缓冲中进行读取;对TestIO.out文件进行操作时,
		 * 先把格式化后的信息输出 到缓存中,再把缓存中的信息输出到文件中。
		 */
		try {
			BufferedReader in4 = new BufferedReader(new StringReader("zhxing"));
			PrintWriter out1 = new PrintWriter(new BufferedWriter(
					new FileWriter("F:\\java\\ TestIO.out")));
			int lineCount = 1;
			String s = null;
			while ((s = in4.readLine()) != null)
				out1.println(lineCount++ + ":" + s);
			out1.close();
			in4.close();
		} catch (EOFException ex) {
			System.out.println("End of stream");
		}

		// 5. 数据的存储和恢复
		/*
		 * 对Data.txt文件进行输出时,是先把基本类型的数据输出屋缓存中,再把缓存中的数据输出到文件中;对文件进行读取操作时,先把文件中的数据读取到缓存中,再从缓存中以基本类型的形式进行读取。注意in5.readDouble()这一行。因为写入第一个writeDouble(),所以为了正确显示。也要以基本类型的形式进行读取。
		 */
		try {
			DataOutputStream out2 = new DataOutputStream(
					new BufferedOutputStream(new FileOutputStream(
							"F:\\java\\ Data.txt")));
			out2.writeDouble(3.1415926);
			out2.writeChars("\nThas was pi:writeChars\n");
			out2.writeBytes("Thas was pi:writeByte\n");
			out2.close();
			DataInputStream in5 = new DataInputStream(new BufferedInputStream(
					new FileInputStream("F:\\java\\ Data.txt")));
			BufferedReader in5br = new BufferedReader(
					new InputStreamReader(in5));
			System.out.println(in5.readDouble());
			System.out.println(in5br.readLine());
			System.out.println(in5br.readLine());
		} catch (EOFException e) {
			System.out.println("End of stream");
		}

		// 6. 通过RandomAccessFile操作文件
		// 通过RandomAccessFile类对文件进行操作。
		RandomAccessFile rf = new RandomAccessFile("F:\\java\\ rtest.dat", "rw");
		for (int i = 0; i < 10; i++)
			rf.writeDouble(i * 1.414);
		rf.close();
		rf = new RandomAccessFile("F:\\java\\ rtest.dat", "r");
		for (int i = 0; i < 10; i++)
			System.out.println("Value " + i + ":" + rf.readDouble());
		rf.close();
		rf = new RandomAccessFile("F:\\java\\ rtest.dat", "rw");
		rf.seek(5 * 8);
		rf.writeDouble(47.0001);
		rf.close();
		rf = new RandomAccessFile("F:\\java\\ rtest.dat", "r");
		for (int i = 0; i < 10; i++)
			System.out.println("Value " + i + ":" + rf.readDouble());
		rf.close();
	}

}

 

 

  • 大小: 31.7 KB
  • 大小: 111.6 KB
  • 大小: 13.2 KB
  • 大小: 104.9 KB
  • 大小: 15.3 KB
  • 大小: 5.2 KB
5
0
分享到:
评论
3 楼 BabyDuncan 2011-02-10  
很不错,我喜欢。
2 楼 tjlvan 2010-11-02  
写的很明白 多谢
1 楼 xiaoqing20 2010-03-23  
路过路过,

相关推荐

    java输入输出流详解.doc

    ### Java 输入输出流详解 #### 一、I/O流概述 在Java中,输入输出流是处理文件读写、网络通信等数据交换的基础。Java提供了丰富的API来支持这些操作,主要包括`java.io`包下的各类流对象。这些流对象按照处理的...

    java输入输出流 流式输入与输出

    【Java输入输出流详解】 Java输入输出流(Input/Output Stream)是Java平台核心API的重要组成部分,主要用于处理数据的输入和输出。Java的I/O机制是基于流的,即数据以流的形式从一个地方传输到另一个地方。Java的I...

    Java文件的输入输出流实例详解

    Java 文件的输入输出流实例详解 Java 文件的输入输出流实例详解是指在 Java 中对文件的输入输出操作的详细介绍。输入输出流是一个通道,程序可以通过这个通道读取源中的数据或将数据传送到目的地。 概念部分: ...

    Java输入输出流及文件读写详解

    ### Java 输入输出流及文件读写详解 #### I/O 类体系结构 在Java开发中,输入输出(I/O)操作是非常重要的部分,特别是在处理文件、网络通信等方面。Java的I/O类体系主要位于`java.io`包中,此外还有一些新实现的I...

    java中的标准输入输出流

    ### Java中的标准输入输出流知识点详解 #### 一、Java标准I/O介绍 Java提供了丰富的I/O处理机制,包括标准输入输出流、字节流、字符流等多种方式来处理数据的读取和写入。标准输入输出流是Java中非常基础且重要的...

    Java_输入输出流及文件读写详解

    Java 输入输出流(I/O 流)是Java平台的核心特性之一,用于处理数据的传输,包括文件读写、网络通信等。在Java API中,I/O流被组织为一系列类和接口,主要位于`java.io`包。在JDK 1.0中引入了字节流(byte stream)...

    第6章(输入输出流).ppt

    【Java输入输出流详解】 Java中的输入/输出流(I/O流)是处理程序与外部交互数据的关键组件。第6章主要围绕Java的I/O流展开,包括输入流、输出流以及文件读写操作。 6.1 输入/输出流 在Java中,I/O流是一个抽象...

    Java_输入输出流及文件读写详解.docx

    "Java 输入输出流及文件读写详解" 本文档对 Java 中的输入输出流和文件读写进行了详细的介绍。从 I/O 类的体系结构开始,讲解了 Java 中的输入输出流的分类,包括字节流和字符流,以及它们之间的区别。然后,着重...

    Java输入输出流实例详解

    Java 输入输出流实例详解 Java 输入输出流是一种基本的数据交换方式,用于在程序之间或程序与外部设备之间交换数据。在 Java 中,输入输出流主要分为两大类:字节流和字符流。字节流用于处理二进制数据,而字符流...

    浅谈Java的输入输出流

    ### Java输入输出流基础知识 #### 一、引言 Java作为一种广泛应用的编程语言,其强大的输入输出(IO)处理能力是其重要的特性之一。通过Java IO库,开发者能够轻松地处理各种类型的输入输出操作,包括但不限于文件...

    Java输入数据流详解

    Java IO包提供了丰富的输入输出类,不仅限于字节流和字符流,还包括对象流(用于序列化和反序列化)、转换流(将字节流与字符流相互转换)以及过滤流(提供额外的功能,如缓冲、字符编码转换等)。这些类和接口共同...

    Java输入/输出流体系详解

    Java输入/输出流体系详解 Java输入/输出流体系是Java语言中非常重要的一部分,它涉及到字节流和字符流、输入输出体系、转换流,以及文件的读写等相关内容。下面将对Java输入/输出流体系进行详细的解释和分析。 ...

    java 输入输出

    ### Java 输入输出流详解 #### 一、Java IO 概述 Java的输入输出功能非常强大且灵活,但实现起来可能会因为需要处理多种类型的对象而显得不够简洁。Java IO库覆盖了广泛的领域,如标准输入输出、文件操作、网络数据...

    Java_IO流详解

    Java 中 IO 是以流为基础进行输入输出的,所有数据被串行化写入输出流,或者从输入流读入。在项目开发中,IO 是非常基础的部分,在面试当中经常出现。对于初学者而言,IO 部分是容易忽略的内容,求职者一定要掌握该...

    JAVA实验报告三java输入输出.docx

    实验报告三:Java输入输出 本实验主要涵盖了Java中输入输出的基本操作,旨在让学生深入理解数据流的概念,熟悉Java流的层次结构,并掌握文件的读写操作。实验内容包括从键盘接收用户输入并在屏幕上显示,读取并显示...

    java中的io流详解

    Java 中的 IO 流详解 Java 中的 IO 流是指在 Java 语言中对输入输出操作的抽象,主要用于实现程序与外部设备和其他计算机之间的交流,尤其是对磁盘文件的操作。IO 流的概念是在 1984 年由 C 语言第一次引入的,后来...

    corejava输入输出流学习总结.pdf

    根据提供的文档信息,本文将对Java中的输入输出流(I/O)进行详细的总结与解析,主要涵盖以下几个方面: 1. **文件操作与File类的基本使用**; 2. **输入输出流的基本概念及其分类**; 3. **字节流的具体实现与应用...

Global site tag (gtag.js) - Google Analytics