Java I/O

Java I/O是Java中很重要的组成部分

一.以字节为向导的Stream InputStream/OutputStream

Java I/O最基本的概念就是输入流与输出流,即InputStream(输入流)和OutputStream(输出流)

InputStream

最基本的字节输入流,抽象类,定义了读取原始字节的所有基本方法

  • read() 读取一个字节的方法
  • close() 关闭stream方法,这个是每次在用完流之后必须调用的方法。
  • available() 返回stream中的可读字节数,inputstream类中的这个方法始终返回的是0,这个方法需要子类去实现。
  • skip(long n) 从stream中跳过long类型参数个位置
  • read(byte b[]) 一次性读取内容到缓冲字节数组
  • read(byte b[],int off,int len) 从数据流中的哪个位置offset开始读长度为len的内容到缓冲字节数组

下面还有三个方法:

  • mark(int readlimit) 用于标记stream的作用
  • markSupported() 返回的是boolean类型,因为不是所有的stream都可以调用mark方法的,这个方法就是用来判断stream是否可以调用mark方法和reset方法
  • reset() 这个方法和mark方法一起使用的,让stream回到mark的位置。
OutputStream

最基本的字节输出流,抽象类,定义了读取原始字节的所有基本方法

  • write(int b) 写入一个字节到stream中
  • close() 关闭流,这个是在操作完stream之后必须要调用的方法
  • flush() 这个方法是用来刷新stream中的数据,让缓冲区中的数据强制的输出
  • write(byte b[]) 写入一个byte数组到stream中
  • write(byte b[], int off, int len) 把byte数组中从offset开始处写入长度为len的数据
总结

InputStream和OutputStream定义了I/O领域最基础的行为,也就是读取和写入一个字节,同时使用了模板方法将读取和写入的行为进行了适当扩展。

扩展一:对I/O流的继承

InputStream和OutputStream都是抽象类,它们仅仅定义了I/O领域最基础的方法,但不涉及具体实现。针对不同的数据来源,InputStream和OutputStream存在三种实现:一种是基于内存的ByteArrayInputStream/ByteArrayOutputStream,一种是基于磁盘文件的FileInputStream/FileOutputStream,还有一种是基于网络的SocketInputStream/SocketOutputStream。

FileInputStream/FileOutputStream

读取写入的源是操作系统的文件使用native方法进行底层文件的读取

try  
{  
    //使用FileInputStream和FileOutputStream进行文件复制  
    FileInputStream fis=new FileInputStream("a.txt");  
    FileOutputStream fos=new FileOutputStream("b.txt");  
    int read;  
    //read=fis.read();  
    byte b[]=new byte[1024];  
    //读取文件,存入字节数组b,返回读取到的字符数,存入read,默认每次将b数组装满  
    read=fis.read(b);  
    while(read!=-1)  
    {  
        fos.write(b,0,read);  
        read=fis.read(b);  
        //read=fis.read();  
    }  
    fis.close();  
    fos.close();  
}  
catch (IOException e)  
{  
    e.printStackTrace();  
}  

ByteArrayInputStream/ByteArrayOutputStream

读取写入的源是内存的一个数组,比较少见

SocketInputStream/SocketOutputStream

读取写入远程服务器的数据流使用native方法进行底层文件的读取

除上述3种以外还有别的实现如下

StringBufferInputStream/StringBufferOutputStream

据指定串创建一个读取数据的输入流串

PipedInputStream/PipedOutputStream

实现了pipe的概念,主要在线程中使用,管道输入流是指一个通讯管道的接收端。
一个线程通过管道输出流发送数据,而另一个线程通过管道输入流读取数据,这样可实现两个线程间的通讯。

SequenceInputStream/SequenceOutputStream

把多个In(Out)putStream合并为一个In(Out)putStream,“序列输入(出)流”类允许应用程序把几个输入(出)流连续地合并起来,
并且使它们像单个输入(出)流一样出现。每个输入(出)流依次被读取,直到到达该流的末尾。
然后“序列输入(出)流”类关闭这个流并自动地切换到下一个输入(出)流。

扩展二:对I/O流的扩展
FilterInputStream/FilterOutputStream

FilterInputStream是InputStream一个特殊的子类,它内部有一个很重要的变量如下

protected volatile InputStream in;  

protected FilterInputStream(InputStream in) {  
    this.in = in;  
}  

这说明了FilterInputStream在实例化的时候,要传一个InputStream类的对象进来。

这个类的特殊之处,就是包含了一个InputStream,使得可以在这个InputStream基础上进行多种封装,从而达到装饰的目的。

这个类本身作用不大,但是他的子类比较有作用

DataInputStream/DataOutputStream

这两个类继承了FilterInputStream/FilterOutputStream,用来实现将java基本类型转换成二进制来进行读写操作,readInt,readFloat,readDouble...这样可以直接从stream中读取基本类型的数据

BufferedInputStream/BufferedOutputStream

继承了FilterInputStream,实现了输入流处理中的缓冲的功能。底层的流会先被读取到一个字节数组中,用户使用BufferedInputStream读取数据的时候,会先读取字节数组中的数据,读完了才会调用底层的流进行进一步的读取。这种方法可以提升读取的性能。继承了FilterOutputStream,实现了输出流处理中的缓冲功能。当用户写入数据的时候,其实是先写入到BufferedOutputStream的一个字节数组中,当这个字节数组满了,才会真正调用底层的输出流执行输出动作。这种方法可以提升写入的性能。在使用BufferedOutputStream的写入功能时,一定要使用flush,因为缓冲数组不满的时候是不会写入底层流的,在写入最后一点数据的时候,缓冲数据不一定被填满,这时候就需要调用flush进行强制刷新。

PrintStream

继承FilterOutputStream,这个类的print和println方法可以把java的一些基本类型数据转换成字节写入到底层输出流,但是PrintStream对String的转换是平台相关的,不同的平台会有不同的编码,所以写入到底层的字节也不同,因此PrintStream只适合于测试输出,不适合于一般的I/O操作,特别是网络流。

PushbackInputStream

继承了FilterInputStream,提供了一种回退的机制,可以实现unread,本质是使用缓冲数组实现了,也就是说,回退的范围是有限的。

二.以字符为向导的Stream Reader/Writer

InputStream和OutputStream是面向字节的,而人类的习惯是面向字符,因此InputStream和OutputStream对于程序猿的用户体验不是太好,于是就需要提供一些面向字符的流。由于DataInputStream/DataOutputStream在跨平台的情况下存在问题,因此,java设计者干脆仿照InputStream和OutputStream重新设计了一套面向字符的I/O,也就是Reader/Writer

Reader

基本的字符输入流,是个抽象类

方法与InputStream对应

Writer

基本的字符输出流,是个抽象类

方法与OutputStream对应

扩展一:对I/O流的继承
CharArrayReader/CharArrayWriter

与前面ByteArrayInputStream/ByteArrayOutputStream对应

StringReader/StringWriter

与前面StringBufferInputStream/StringBufferOutputStream对应

FileReader/FileWriter

与前面FileInputStream/FileOutputStream对应

PipedReader/PipedWriter

与前面PipedInputStream/PipedOutputStream对应

扩展二:对I/O流的扩展

FilterReader/FilterWriter

BufferedReader/BufferedWriter

PushbackReader

PrintWriter

三.两种不同导向的Stream之间的转换

由于计算机只识别字节,所以Reader/Writer的数据来源最终还是字节,而他们无法直接和字节打交道,这时候就需要一个中介者将Reader/Writer和InputStream和OutputStream进行打通,于是就有了InputStreamReader和OutputStreamWriter

InputStreamReader 类是从字节流到字符流的桥梁:它读入字节,并根据指定的编码方式,将之转换为字符流。
使用的编码方式可能由名称指定,或平台可接受的缺省编码方式。

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

为了达到更高效率,考虑用 BufferedReader 封装 InputStreamReader ,
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

![](/Users/admin/Documents/Life/I:O/3400180-bce9503f7c9ee657.png =500x300)

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

推荐阅读更多精彩内容

  • Stream概述 Stream是一个数据流,可以从它读取数据或写入数据。它是连接数据源或数据目的地,例如文件,网络...
    狮_子歌歌阅读 700评论 1 2
  • 一、流的概念和作用。 流是一种有顺序的,有起点和终点的字节集合,是对数据传输的总成或抽象。即数据在两设备之间的传输...
    布鲁斯不吐丝阅读 10,018评论 2 95
  • 主要就是对各种输入输出流使用的总结 字节流使用情况:对流中的数据以字节为单位进行读取写入操作,不关心内容 字符流使...
    任教主来也阅读 556评论 0 1
  • 和自己聊天,是件奢侈的事。 每天的生活中,我们睁开眼睛开始,就是展开了又一天和世界沟通的工作。 工作一上午,看到手...
    伍卄阅读 371评论 0 1
  • 又一个中戏的闺蜜要离开北京了 前前后后陆陆续续的你们说都走几个了?! 没法具体形容听到此消息时的感觉, 有点像冰淇...
    公子茗阅阅读 495评论 0 50