JAVA后端架构—《IO架构体系》

I/O(Input/Output)

stream代表的是任何有能力产出数据的数据源,或是任何有能力接收数据的接收源。
在Java的IO中,所有的stream(包括InputStream和OutStream)都包括两种类型:

1. 字节流

表示以字节为单位从stream中读取或往stream中写入信息,即io包中的inputstream类和outputstream类的派生类。通常用来读取二进制数据,如图象和声音。

2.字符流

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

区别:

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。

一.流的层次结构

定义:
(1) java将读取数据对象成为输入流,能向其写入的对象叫输出流。结构图如下:输入流:

输出流

二.InputStream类

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

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

(1) public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。

(2) public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的

(3) public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。

(4) public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用,

(5) public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取

(6) public int close( ) :我们在使用完后,必须对我们打开的流进行关闭.

三.OutputStream类

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

public void write(byte b[ ]):将参数b中的字节写到输出流。

public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。

public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。

public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。

public void close( ) : 关闭输出流并释放与流相关的系统资源。

注意:

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

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

四.FileInputStream类

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

方式1:

File fin=new File(“d:/abc.txt”);

FileInputStream in=new FileInputStream(fin);

方式2:

FileInputStream in=new FileInputStream(“d: /abc.txt”);

方式3:

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

FileDescriptor() fd=new FileDescriptor();

FileInputStream f2=new FileInputStream(fd);

五.FileOutputStream 类

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

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

方式1:

File f=new File(“d:/abc.txt”);

FileOutputStream out=new FileOutputStream (f);

方式2:

FileOutputStream out=new FileOutputStream(“d:/abc.txt”);

方式3:构造函数将 FileDescriptor() 对象作为其参数。

FileDescriptor() fd=new FileDescriptor();

FileOutputStream f2=new FileOutputStream(fd);

方式4:构造函数将文件名作为其第一参数,将布尔值作为第二参数。

FileOutputStream f=new FileOutputStream(“d:/abc.txt”,true);

注意:

(1)文件中写数据时,若文件已经存在,则覆盖存在的文件;(2)的读/写操作结束时,应调用close方法关闭流。

举例:2-1

六.File类

File类与InputStream / OutputStream类同属于一个包,它不允许访问文件内容。

File类主要用于命名文件、查询文件属性和处理文件目录。

举例:2-2

七.从一个流构造另一个流

java的流类提供了结构化方法,如,底层流和高层过滤流。

而高层流不是从输入设备读取,而是从其他流读取。同样高层输出流也不是写入输出设备,而是写入其他流。

使用"分层对象(layered objects)",为单个对象动态地,透明地添加功能的做法,被称为Decorator Pattern。Decorator模式要求所有包覆在原始对象之外的对象,都必须具有与之完全相同的接口。这使得decorator的用法变得非常的透明–无论对象是否被decorate过,传给它的消息总是相同的。这也是Java I/O类库要有"filter(过滤器)"类的原因:抽象的"filter"类是所有decorator的基类。Decorator模式常用于如下的情形:如果用继承来解决各种需求的话,类的数量会多到不切实际的地步。Java的I/O类库需要提供很多功能的组合,于是decorator模式就有了用武之地。

DataInputStream类对象可以读取各种类型的数据。

DataOutputStream类对象可以写各种类型的数据;

创建这两类对象时,必须使新建立的对象指向构造函数中的参数对象。例如:

FileInputStream in=new FileInputStream(“d:/abc.txt”);

DataInputStream din=new DataInputStream(in);

7.2BufferInputStream和bufferOutputStream

允许程序在不降低系统性能的情况下一次一个字节的从流中读取数据。

BufferInputstream定义了两种构造函数

(1) BufferInputStream b= new BufferInputstream(in);

(2) BufferInputStream b=new BufferInputStream(in,size)

第二个参数表示指定缓冲器的大小。

同样BufferOutputStream也有两种构造函数。一次一个字节的向流中写数据。

7.3printstream

用于写入文本或基本类型

两种构造函数方法:

PrintStream ps=new PrintStream(out);

PrintStream ps=new PrintStream(out, autoflush)

第二个参数为布尔值,控制每次输出换行符时java是否刷新输出流

八.字符流的读取和写入

java.io.Reader 和 java.io.InputStream 组成了 Java 输入类。Reader 用于读入16位字符,也就是 Unicode 编码的字符;而 InputStream 用于读入 ASCII 字符和二进制数据。
Reader的体系结构

(1) FileReader

FileReader 主要用来读取字符文件,使用缺省的字符编码,有三种构造函数:

–将文件名作为字符串

FileReader f=new FileReader(“c:/temp.txt”);

–构造函数将File对象作为其参数。

File f=new file(“c:/temp.txt”);

FileReader f1=new FileReader(f);

–构造函数将FileDescriptor对象作为参数

FileDescriptor() fd=new FileDescriptor()

FileReader f2=new FileReader(fd);

(2) charArrayReader

将字符数组作为输入流,构造函数为:

public CharArrayReader(char[] ch);

(3) StringReader

读取字符串,构造函数如下:

public StringReader(String s);

(4) InputStreamReader

从输入流读取字节,在将它们转换成字符。

Public inputstreamReader(inputstream is);

(5) FilterReader

允许过滤字符流

protected filterReader(Reader r);

(6) BufferReader

接受Reader对象作为参数,并对其添加字符缓冲器,使用readline()方法可以读取一行。

Public BufferReader(Reader r);

Writer类体系结构

(1) FileWrite

将字符类型数据写入文件,使用缺省字符编码和缓冲器大小。

Public FileWrite(file f);

(2)chararrayWrite()

将字符缓冲器用作输出。

Public CharArrayWrite();

(3) PrintWrite

生成格式化输出

public PrintWriter(outputstream os);

(4) filterWriter

用于写入过滤字符流

protected FilterWriter(Writer w);
DataInputStream类对象可以读取各种类型的数据。

DataOutputStream类对象可以写各种类型的数据;

创建这两类对象时,必须使新建立的对象指向构造函数中的参数对象。例如:

FileInputStream in=new FileInputStream(“d:/abc.txt”);

DataInputStream din=new DataInputStream(in);

7.2BufferInputStream和bufferOutputStream

允许程序在不降低系统性能的情况下一次一个字节的从流中读取数据。

BufferInputstream定义了两种构造函数

(1) BufferInputStream b= new BufferInputstream(in);

(2) BufferInputStream b=new BufferInputStream(in,size)

第二个参数表示指定缓冲器的大小。

同样BufferOutputStream也有两种构造函数。一次一个字节的向流中写数据。

7.3printstream

用于写入文本或基本类型

两种构造函数方法:

PrintStream ps=new PrintStream(out);

PrintStream ps=new PrintStream(out, autoflush)

第二个参数为布尔值,控制每次输出换行符

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容