这部分对应Thinking in JAVA 3rd的P488-P585,这部分的内容在Thinking in JAVA这本书上写得很难看懂,于是搜罗了google上的几篇文章,这里转载这两篇文章。
出处:http://hzxdark.iteye.com/blog/40133
这篇文章主要介绍了decorator设计模式,这是JAVAIO的基础
我不知道各位是师弟师妹们学java时是怎样的,就我的刚学java时的感觉,java.io包是最让我感到一头雾水的。所以现在这篇文,尽可能简单地描述java.io包的结构,希望对java.io同样一头雾水的师弟师妹们有些帮助^_^
我开始学java时,java.io的介绍是在《java编程思想》里看的。说实话,当时完全看不明白——“java.io的是用‘decorator模式’来构建的”——刚学java时,天知道啥玩意叫decorator……
不过要明白java.io,确实需要理解decorator设计模式,下面详细介绍下。
所谓decorator,装饰,其实可以说是一种设计的技巧,说白了没什么难的,别看很多网上资料说的天花乱坠的(非常讨厌有些文章总是把简单的问题描述得跟两头猪的kiss问题一样复杂……)。
decorator的结构如下:
MyInterface
|
_______|_______
| |
Myclass Decorator
____|_____
| |
DecoratorA DecoratorB
decorator的目的是在不改变任何原有的类的基础下,添加新的功能(你可以理解为书上说的灵活性)。其中Myclass是你要扩展的类,DecoratorA跟DecoratorB封装了你要扩展的功能,并保存有一个MyInterface的引用。
考虑以下代码:
public static void main(Strings[] arg){
myInterface a = new myClass();
a.print();
}
myInterface 是myClass的接口,只声明了一个方法print(),myClass实现了该方法:
public void print(){
System.out.println("hello");
}
那么假如我们要在不改变原来的myClass的基础上,变成输出“hello world!”,要怎么做呢?
当然我们可以考虑直接写个myClass的子类,helloClass之类,但是要是要求根据环境不同,输出"hello world!",my hello world","my Hello"之类的组合呢?
用继承的方式将不得不写一堆类似的子类来。
decorator,装饰模式的解决方法是,只实现基本的功能,把附加的功能抽出来放一边。
例如以下代码:
class DecoratorA implements Decorator{
MyInterface myObject;
DecoratorA(myInterface myObject){
this.myObject = myObject;
}
public void print(){
myObject.print();
System.out.print("world!");
}
}
class DecoratorB implements Decorator{
MyInterface myObject;
DecoratorA(myInterface myObject){
this.myObject = myObject;
}
public void print(){
System.out.print("my");
myObject.print();
}
}
DecoratorA和DecoratorB的功能分别是打印出world跟my。这时main函数要打印出my hello world可简单变为:
public static void main(Strings[] arg){
MyInterface a =new DecoratorA(new DecoratorB(new MyClass());
a.print();
}
简单吧?简单的说,就是:
print(){
print("xxx");//可替换成你要添加的任何处理;
myObject.print();//调用基础类的函数;
xxxx; //后续处理
}
Decorator的介绍就到此为止,接下来讲java.io.
看到
MyInterface a =new DecoratorA(new DecoratorB(new MyClass());
是不是觉得眼熟咧?这跟
BufferedInputStream bis = new BufferedInputStream(new DataInpuStream(new FileInputStream("xxx.txt")));
是不是很像?
(画外音加一个臭鸡蛋扔上来:因为java.io就是用decorator模式组织的,当然像啦……)
java.io分Stream跟reader、writer两大类,这里只详细介绍Stream,并最后两者间的关系。Stream又分inputStream、OutputStream,两者基本是对称的,这里也只介绍InputStream.
java.io.InputStream
|
_______________________|________________________
| |
ByteArrayInputStream FilterInputStream
StringBufferInputStream _____________________|____________________________
FileInputStream | | | |
PipedInputStream DataInputStream BufferedInputStream LineNumInpuStream XXX
(注:xxx是PushbackInputStream,上面的图放不下)
这个图跟最初介绍的hello world的图很像吧?呵呵。
基础的流只有左边4个,这些流代表了数据的来源,所有的流都必须从这四个中之一开始。(注,还有一个RandomAccessFile、File,这两个不在本文介绍范围)。
然后当我们需要什么添加功能,就从右边中选择一个装饰。例如,我们需要缓存功能,那么需要bufferedInputStream装饰:
BufferdInputStream is = new BufferedInputStream(new FileInputStream("xxx.txt"));
假如再要DataInputStream的功能,只要在加一层:
DataInputStream dis = new DataInputStream(new BufferdInputStream(new FileInputStream));
(厄,我不甚明白这个类添加的功能是做什么用的,资料说是增加读取java原生数据的功能,不甚明白,有清楚的来补充一下,pipeInputStream跟sequenceInputStream也没用过,欢迎补充说明)
这里你可以想象成,在基本的FileInputStream.readxxx()方法在BufferedInputStream的readxxx()方法调用,并添加相应的处理。
下面这篇是对JAVA IO类的概要性介绍
出处:http://blog.csdn.net/wolfpkfox/archive/2009/01/02/3680931.aspx
Java.io基本上包含三种类
1建立数据流的类(处理字节流,字符流)
2用于序列化的类和接口(字节流与字符流之间进行转换)
3 处理文件系统的类和接口(对文件进行操作)
InputStream/OutputStream是所有字节输入输出流的超类
以字节为导向的stream,表示以字节为单位从stream中读取或往stream中写入信息
Reader/Writer是所有字符输入输出流的超类
以Unicode字符为导向的stream,表示以Unicode字符为单位从stream中读取或往stream 中写入信息。
输入/输出流是按数据源而提供类的,如字节数组,String对象,文件,管道,序列,其他数据源等Java IO的一般使用原则:
一、按数据来源(去向)分类:
1、是文件: FileInputStream, FileOutputStream, FileReader, FileWriter
2、是byte[]:ByteArrayInputStream, ByteArrayOutputStream
3、是Char[]: CharArrayReader, CharArrayWriter
4、是String: StringBufferInputStream, StringReader, StringWriter
5、网络数据流:InputStream, OutputStream, Reader, Writer
二、按是否格式化输出分:
1、要格式化输出:PrintStream, PrintWriter
三、按是否要缓冲分:
1、要缓冲:BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter
四、按数据格式分:
1、二进制格式(只要不能确定是纯文本的): InputStream, OutputStream及其所有带Stream结束的子类
2、纯文本格式(含纯英文与汉字或其他编码方式);Reader, Writer及其所有带Reader, Writer的子类
五、按输入输出分:
1、输入:Reader, InputStream类型的子类
2、输出:Writer, OutputStream类型的子类
六、特殊需要:
1、从Stream到Reader,Writer的转换类:InputStreamReader, OutputStreamWriter
2、对象输入输出:ObjectInputStream, ObjectOutputStream
3、进程间通信:PipeInputStream, PipeOutputStream, PipeReader, PipeWriter
4、合并输入:SequenceInputStream
5、更特殊的需要:PushbackInputStream, PushbackReader, LineNumberInputStream, LineNumberReader
决定使用哪个类以及它的构造进程的一般准则如下(不考虑特殊需要):
首先,考虑最原始的数据格式是什么: 原则四
第二,是输入还是输出:原则五
第三,是否需要转换流:原则六第1点
第四,数据来源(去向)是什么:原则一
第五,是否要缓冲:原则三 (特别注明:一定要注意的是readLine()是否有定义,有什么比read, write更特殊的输入或输出方法)
第六,是否要格式化输出:原则二
1.1 以字节为导向的stream
以字节为导向的stream,表示以字节为单位从stream中读取或往stream中写入信息。以字节为导向的stream包括下面几种类型:
1) InputStream:
1) ByteArrayInputStream:把内存中的一个缓冲区作为InputStream使用
2) StringBufferInputStream:把一个String对象作为InputStream
3) FileInputStream:把一个文件作为InputStream,实现对文件的读取操作
4) PipedInputStream:实现了pipe的概念,主要在线程中使用
5) SequenceInputStream:把多个InputStream合并为一个InputStream
2) OutputStream
1) ByteArrayOutputStream:把信息存入内存中的一个缓冲区中
2) FileOutputStream:把信息存入文件中
3) PipedOutputStream:实现了pipe的概念,主要在线程中使用
4) SequenceOutputStream:把多个OutStream合并为一个OutStream
1.2 以Unicode字符为导向的stream
以Unicode字符为导向的stream,表示以Unicode字符为单位从stream中读取或往stream中写入信息。以Unicode字符为导向的stream包括下面几种类型:
1) InputStream
1) CharArrayReader:与ByteArrayInputStream对应
2) StringReader:与StringBufferInputStream对应
3) FileReader:与FileInputStream对应
4) PipedReader:与PipedInputStream对应
2) OutputStream
1) CharArrayWriter:与ByteArrayOutputStream对应
2) StringWriter:无与之对应的以字节为导向的stream
3) FileWriter:与FileOutputStream对应
4) PipedWriter:与PipedOutputStream对应
以字符为导向的stream基本上对有与之相对应的以字节为导向的stream。两个对应类实现的功能相同,字是在操作时的导向不同。如CharArrayReader:和ByteArrayInputStream的作用都是把内存中的一个缓冲区作为InputStream使用,所不同的是前者每次从内存中读取一个字节的信息,而后者每次从内存中读取一个字符。
1.3 两种不现导向的stream之间的转换
InputStreamReader和OutputStreamReader:把一个以字节为导向的stream转换成一个以字符为导向的stream。
2. stream添加属性
2.1 "为stream添加属性"的作用
运用上面介绍的Java中操作IO的API,我们就可完成我们想完成的任何操作了。但通过FilterInputStream和FilterOutStream的子类,我们可以为stream添加属性。
如果我们要往一个文件中写入数据,我们可以这样操作:
FileOutStream fs = new FileOutStream("test.txt");
然后就可以通过产生的fs对象调用write()函数来往test.txt文件中写入数据了。但是,如果我们想实现"先把要写入文件的数据先缓存到内存中,再把缓存中的数据写入文件中"的功能时,上面的API就没有一个能满足我们的需求了。但是通过FilterInputStream和FilterOutStream的子类,为FileOutStream添加我们所需要的功能。
2.2 FilterInputStream的各种类型
2.2.1 用于封装以字节为导向的InputStream
1) DataInputStream:从stream中读取基本类型(int、char等)数据。
2) BufferedInputStream:使用缓冲区
3) LineNumberInputStream:会记录input stream内的行数,然后可以调用getLineNumber()和setLineNumber(int)
4) PushbackInputStream:很少用到,一般用于编译器开发
2.2.2 用于封装以字符为导向的InputStream
1) 没有与DataInputStream对应的类。除非在要使用readLine()时改用BufferedReader,否则使用DataInputStream
2) BufferedReader:与BufferedInputStream对应
3) LineNumberReader:与LineNumberInputStream对应
4) PushBackReader:与PushbackInputStream对应
2.3 FilterOutStream的各种类型
2.2.3 用于封装以字节为导向的OutputStream
1) DataIOutStream:往stream中输出基本类型(int、char等)数据。
2) BufferedOutStream:使用缓冲区
3) PrintStream:产生格式化输出
2.2.4 用于封装以字符为导向的OutputStream
1) BufferedWriter:与对应
2) PrintWriter:与对应
3. RandomAccessFile
1) 可通过RandomAccessFile对象完成对文件的读写操作
2) 在产生一个对象时,可指明要打开的文件的性质:r,只读;w,只写;rw可读写
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wolfpkfox/archive/2009/01/02/3680931.aspx
接下来是我写的一些联系代码,以及对此的一些分析
1.标准输入输出字符串
System.out.println("Test stdin & stdout");
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
String buf;
try {
while ((buf = stdin.readLine()) != null){
System.out.println(buf);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
这个是从标准输入输出端获取键盘输入并打印的例子。没有什么复杂的东西,唯一注意的是这个类InputStreamReader,这个类的作用是把一个InputStream转换为Reader(System.in是一个InputStream),类似的还有OutputStream
2.保存字符串到文件
System.out.println("Test charactors file out");
BufferedReader stdin2 = new BufferedReader(new InputStreamReader(System.in));
File file = new File("output.out");
if (!file.exists()){
file.createNewFile();
}
BufferedWriter fout = new BufferedWriter(new FileWriter(file));
String buf;
while ((buf = stdin2.readLine()) != null){
fout.write(buf + "\r\n");
}
fout.close();
注意,由于我们使用了BufferedWriter来写文件,所以写文件的时候并不会直接写到文件当中去而是写到一个缓冲区中,直到缓冲区满才写入文件。所以,如果不调最后个fout.close()的话,你看到的会是一个0字节的文件。另外无论是写文件还是读文件,最后都应该调close来把文件关掉。
3.数据(int/double等)及字符串的文件写入/读取
System.out.println("Test data file out & in");
File file = new File("output2.out");
if (!file.exists()){
file.createNewFile();
}
DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
int nTest = 7;
double ndouble = 3.1415926;
String strTest = "this is a test string\n";
dout.writeInt(nTest);
dout.writeDouble(ndouble);
dout.writeBytes(strTest);
dout.close();
nTest = 0;
ndouble = 0;
strTest = "zero";
DataInputStream din = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
nTest = din.readInt();
ndouble = din.readDouble();
BufferedReader fin = new BufferedReader(new InputStreamReader(din));
strTest = fin.readLine();
fin.close();
din.close();
System.out.println("int = " + nTest + "\ndouble = " + ndouble);
System.out.println("string = " + strTest);
DataInputStream和DataOutputStream两个类是用来从文件中写入/读取一些基本类型的,你可以看到这里有一串的wrtiexxxx和readxxx方法,另外的操作都是一样的。
分享到:
相关推荐
【Java自学笔记】 Java是一种广泛使用的面向对象编程语言,其设计思想主要基于对象、类、继承、封装和消息传递等核心概念。面向对象编程(OOP)旨在通过模拟现实世界中的实体来构建软件系统,使得代码更加易于理解...
Java IO流处理是Java编程中一个非常重要的概念,主要用于数据的输入和输出操作。对于Java初学者来说,理解和掌握IO流的基本使用至关重要。在Java中,流被形象地比喻为数据传输的通道,数据可以从一个源头(如文件、...
从提供的文件内容中,可以提取出与Java编程语言相关的...综合以上内容,这份自学笔记详细涵盖了Java的基础语法、面向对象编程、异常处理、标准库的使用等多个核心知识点,适合初学者通过学习和练习来提高Java编程能力。
Java自学笔记概述 Java是一种广泛使用的面向对象的编程语言,由Sun Microsystems(现已被Oracle公司收购)于1995年发布。这份“java自学笔记”涵盖了从基础到进阶的多个Java知识点,旨在帮助初学者系统地学习并掌握...
Java自学笔记是一个逐步积累的过程,涵盖了许多核心概念和实践技巧。这份笔记的目的是帮助初学者系统地理解并掌握Java这门强大的编程语言。下面将详细阐述一些关键知识点,旨在为你的学习之路提供清晰的指导。 1. *...
5. **IO流**:Java的输入/输出流系统支持对文件、网络和其他数据源的数据读写。学习BufferedReader、FileReader、FileWriter等类,理解流的方向、类型以及缓冲区的概念。 6. **多线程**:Java提供了并发编程的支持...
### Core Java 自学笔记知识点概览 #### 一、Java概况介绍 - **Java之父**: James Gosling,被尊称为“Java之父”。 - **诞生日期**: 1995年5月23日。 - **重要版本**: - 1998年12月发布的1.2版本标志着Java 2的...
Java是一种广泛使用的面向对象的编程语言,以其跨...对于自学Java的人来说,这是一份很好的指导资料,可以帮助他们系统地学习和理解Java语言。通过深入阅读并实践其中的示例,初学者可以逐步建立起扎实的Java编程基础。
《黑马程序员Java基础笔记》是一份全面覆盖Java编程基础知识的学习资料,旨在帮助初学者迅速掌握Java编程语言,能够独立编写...这份笔记不仅覆盖了Java语言的核心概念,还提供了实际应用的示例,是自学Java的宝贵资源。
这份“java经典自学程序及学习笔记心得”压缩包是学习Java编程的宝贵资源,包含了实战程序和作者的学习经验,旨在帮助初学者和进阶者更好地理解和掌握Java技术。 一、Java经典程序 Java经典程序通常包括了基础语法...
黑马Java基础笔记是一份详尽的教程,旨在帮助初学者或自学人员扎实地掌握Java编程的基础。 首先,笔记可能涵盖了Java语言的基础语法,包括数据类型、变量、常量和运算符。Java提供了两种主要的数据类型:基本类型...
### Java学习笔记知识点详解 #### 一、Java面向对象编程思想 面向对象编程(Object-Oriented Programming, OOP)是Java的核心特性之一。通过封装、继承和多态这三个基本特征来实现。OOP能够提高代码的复用性和可...
总的来说,这份"java笔记-从浅入深的入门学习"涵盖了Java编程的各个方面,从基本概念到高级特性,是初学者理想的自学资料。通过系统学习和实践,你将能够逐步掌握这个强大而灵活的编程语言,并为未来的进阶学习打下...
import java.io.InputStreamReader; import java.net.URL; import java.util.HashSet; import java.util.Set; public class WebCrawler { private Set<String> visitedUrls; public WebCrawler() { visitedUrls...
学习Java需要掌握基础语法、类与对象、异常处理、多线程、IO流、网络编程等核心概念。 2. **JSP**: JSP是Java的一个扩展,主要用于开发动态Web页面。它将HTML、CSS、JavaScript与Java代码结合在一起,使得开发者...
【Java学习笔记详解】 在Java的学习旅程中,基础至关重要。这份“学习笔记 十分有用 java”涵盖了J2SE(Java Standard Edition)的基础知识,旨在...无论你是自学Java,还是准备面试,这份笔记都将提供极大的帮助。
本笔记由北京MLDN学堂的李老师精心编写,旨在为自学者提供一套经典的学习资源,帮助他们扎实地理解JAVA的基础概念。 笔记内容涵盖了多个核心主题: 1. **01Java基础部分重要知识(一)**:这部分主要讲解JAVA的基础...
这份笔记涵盖了从基础语法到高级特性的全面内容,是初级Java程序员理想的自学资料。下面将对其中可能涉及的知识点进行详细阐述。 1. **Java简介与环境配置** - Java的历史和发展:了解Java语言的起源、主要版本...
【Java基础】 ...这份MLDN老师的Java笔记全面涵盖了以上知识点,对于自学Java的人来说,是极好的学习资源。通过深入理解和实践这些内容,可以扎实掌握Java编程基础,为进一步的学习和开发打下坚实的基础。