IO流

# Java 流式输入 输出原理

# Java 流的分类

# 输入 输出 流 类

# 常见的节点流 和 处理流

# 文件流

# 缓冲流

# 数据流

# 转换流

# Print流

# Object 流

Java 流式输入 输出 原理

在Java程序中 对于数据的输入 输出操作以 流 stream方式进行,J2SDK 提供了各种各样的 流 类,用以获取不同种类的数据 程序中通过标准的方法 输入或输出数据

File封装的是文件的文件名,真正的文件是硬盘上的一块空间,文件内存着各种数据,通过流的方式读取文件内的数据。对于计算机而言,读取计算机的文件都是0101,

将文件 模拟成 一个桶  读取文件内的数据,可以通过 在桶上安装一个管道,然后打开水龙头 开始出水, 这根管道就叫做流,Java里流式的输入输出 与水流的原理相同,从文件内读取数据时,安插一个管道读取数据,写数据时,往文件上插入管道,一直灌水。

这个文件可以是硬盘上或者内存里的文件,也可以是网络上的数据,连接对方的某一端口,有的时候 管道内的水不是你想要的纯净水 有一些杂质 需要过滤,这个时候需要 在外面再包一层管道,就是对0101字节数据 再进行一些封装,转换成字符串(管道)。流式原理中最重要的就是这些不同的管道。

Java流式输入输出原理

输入 输出流的分类:

java.io 包中定义了多个流类型(类或抽象类)实现输入输出功能,可以从不同角度对其进行分类:

按照数据流的方向可以分为:输入流和输出流,按照处理数据的单位可以分为字节流和字符流。按照功能不同可以分为节点流和处理流。

J2SDK所提供的所有流类型位于Java.io内都分别继承自以下四种抽象流类型:


输入 输出流的分类

                   字节流              字符流(四个抽象流)

输入流       InputStream      Reader

输出流       OutputStream    Writer

接入文件读取文件的数据,针对文件而言是输出,针对程序而言是输入,我们是从程序的角度出发。

字节流:读出的数据是010101  8位一个字节的读取。

字符流:一个字符 一个字符 两个字节的处理  Java是unicode字符串  UTF-16

节点流和处理流

节点流:管道直接连接到数据源,即可以从一个特定的数据源(节点)读写数据。(如 文件 内存)

处理流:如果对原始的节点流 处理的不合适 可以在流处理时  套入其他管道,即“”“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序员提供更为强大的读写功能。  水流里有杂质,一层层过滤 处理,针对数据提供更高级的处理,更强大的读写功能。

InputStream


字节流输入子类图

继承自InputStream(抽象类)的流都是用于向程序中输入数据,且数据的单位为字节(8bit),深色为节点流,浅色为处理流。ObjectInputStream  把对象从字节流里读取出来,涉及到对象的序列化。

InputStream的基本方法:


InputStream 基本方法

int read() throws IOException  // 读取一个字节并以整数形式返回 0-255,如果返回-1就到输入流的末尾  每次读取一个字节 每次读取一个字节

int read(byte[] buffer) throws IOException // 读取一系列字节并存储到一个数组Buffer(内存中的缓冲区),返回实际读取的字节数,如果读取前已到输入流的末尾返回-1   将buffer字节数组填满数据之后,再进行处理。 电驴 下载 p2p软件比较毁硬盘,读取比较频繁,容易损伤,不能每次读取一个字节访问一次硬盘。在内存里开辟一个空间,读一次硬盘将该空间(字节数组)装满,大大减少对硬盘的访问次数。写的时候,将该空间填满,再一次性写进硬盘。减少对硬盘的访问次数。

int read(byte[] buffer,int offset,int length) throws IOException  // 读取length个字节,并存储到一个字节数组buffer 从offset位置开始 返回实际读取的字节数 如果读取前已到输入流的末尾返回-1

void close() throws IOException // 关闭流释放内存资源

long skip(long n) throws IOException // 跳过n个字节不读,返回实际跳过的字节数

OutputStream:


OutputStream

继承自OutputStream的流是用于程序中输入数据,且数据的单位为字节(8bit):深色为节点流、浅色为处理流。

OutputStream的基本方法


OutputStream 基本方法

void write(int b) throws IOException // 向输出流写入一个字节数据,该字节数据为参数b的低8位

void write(byte[] b) throws IOException // 将一个字节类型的数组中的数据写入输出流

void write(byte[] b,int off,int len) throws IOException // 将一个字节类型的数组从指定位置off 开始的len个字节写入到输出流

void close() throws IOException // 关闭流释放内存资源

void flush() throws IOException // 将输出流中缓冲的数据全部写到目的地


close之前需要flush

close 之前调用flush,close比较粗暴 直接关闭流释放了内存资源,假如此时缓冲区尚有部分数据为通过“管道”写入到目的地。

Reader:

继承自Reader的流都是用于向程序中输入数据,且数据的单位为字符,两个字节,16bit,下图中深色为节点流,浅色为处理流。

Reader

中文字符在Java 中是两个字节的存在,为了保障其能正常显示,必须一个字符一个字符即两个字节两个字节的读取。

Reader的基本方法:


Reader的基本方法

int read() throws IOException  // 读取一个字符并以整数形式返回 0-255,如果返回-1就到输入流的末尾  每次读取一个字符 每次读取一个字符

int read(char[] cbuffer) throws IOException // 读取一系列字符并存储到一个数组Buffer(内存中的缓冲区),返回实际读取的字符数,如果读取前已到输入流的末尾返回-1   将buffer字符数组填满数据之后,再进行处理。

int read(char[] cbuffer,int offset,int length) throws IOException  // 读取length个字符,并存储到一个字符数组buffer 从offset位置开始 返回实际读取的字符数 如果读取前已到输入流的末尾返回-1

void close() throws IOException // 关闭流释放内存资源

long skip(long n) throws IOException // 跳过n个字节不读,返回实际跳过的字符数

Writer:

继承自Writer的流都是用于从程序中输出数据,且数据的单位为字符,两个字节,16bit,下图中深色为节点流,浅色为处理流。


Writer的基本方法

Writer的基本方法

void write(int c) throws IOException // 向输出流写入一个字符数据,该字符数据为参数b的低16位

void write(char[] cbuf) throws IOException // 将一个字符类型的数组中的数据写入输出流

void write(char[] cbuf,int off,int len) throws IOException // 将一个字符类型的数组从指定位置off 开始的len个字符写入到输出流

void write(String string) throws IOException // 将一个字符串中的字符写入输出流

void write(String string,int off,int len) throws IOException // 将一个字符串从off开始的len个字符写入到输出流

void close() throws IOException // 关闭流释放内存资源

void flush() throws IOException // 将输出流中缓冲的数据全部写到目的地

节点流类型:

节点流

节点流:直接处理数据源数据的流类,直接处理文件 内存里的数组 内存里的String 以及管道(线程和线程之间通信)


访问文件

访问文件:

FileInputStream 和 FileOutputStream 分别继承自InputStream和OutputStream,用于向文件中输入或输出字节。

FileInputStream和FileOutputStream 常用构造方法:

FileInputStream(String name) throws FileNotFoundException

FileInputStream(File file) throws FileNotFoundException

FileOutputStream(String name) throws FileNotFoundException

FileOutputStream(File file) throws FileNotFoundException (无文件会自动创建该文件 只能建文件 不能建目录)

FileOutputStream(File file,Boolean append) throws FileNotFoundException

FileInputStream和FileOutputStream类支持其父类InputStream和OutputStream所提供的数据读写方法

注意:在实例化FileInputStream和FileOutputStream实例要try-catch 语句以处理其可能抛出的FileNotFoundException。在读写数据时也要用try-catch 语句以处理可能抛出的IOException,是其子类。

\\ 是window下在Java程序中定义的路径分隔符  或者  /    正斜杠

以字节形式读取字符数据的话  无法转换成功  用Reader读取  也可能是编码格式问题


处理流:

处理流

处理节点流或处理流的返回的数据,相当于对数据进行多层封装。


缓冲流

缓冲流要“”“套接在”相应的节点流上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法。四种缓冲流,常用构造:

BufferedReader(Reader in)

BufferedReader(Reader in,int sz) // sz为自定义缓存区的大小

BufferedWriter(Writer out)

BufferedWriter(Writer out,int sz)

BufferedInputStream(InputStream in)

BufferedInputStream(InputStream in,int sz)

BufferedOutputStream(OutputStream out)

BufferedOutputStream(OutputStream out,int size)

缓冲输入流支持其父类的mark和reset方法

BufferedReader提供了readLine方法用于读取一行字符串(以\r或\n分隔)

BufferedWriter提供了newLine用于写入一个行分隔符

对于输出的缓冲流,写出的数据会先在内存中缓存,使用flush方法将会使内存中的数据立刻写出。


处理流与节点流(字节)的管道封装


处理流与节点流(字符)的管道封装

转换流:

字节到字符的转换流

字节流转换为字符流,InputStreamReader和OutputStreamWriter用于字节数据到字符数据知己恩的转换。InputStreamReader需要和InutStream进行“”“套接”,OutputStreamWriter需要和OutputStream“套接”,转换流在构造时可以指定其编码集合,比如: InputStream isr = new InputStreamReader(System.in,"ISO8859_1");

中文window默认编码 gbk


转换流

可以直接写中文和String,比较好用。


字节转字符进行缓冲流处理

首先 字节(阻塞式方法、同步方法 System.in)转字符 然后进行缓冲流处理。

数据流

DataInputStream和DataOutputStream分别继承自InputStream和outputStream,属于处理流,需要分别套接在InputStream和OutputStream类型的节点流上。

DataInputStream和DataOutputStream提供了可以存取与机器无关的原始类型数据(int double)等方法

DataInputStream和DataOutputStream的构造方法:

DataInputStream(InputStream in)

DataOutputStream(OutputStream in)

网络上传输数据时  经常使用ReadUTF()  utf-8 比较省空间 网络上用的比较多

数据流

直接操作原始数据类型的数据读写,比较方便好用。

先写的先读。new DataOutputStream(new ByteArrayOutputStream())

.writeDouble(Math.random())  // 内存中占8个字节 可以同DataOutputStream直接写入

.writeBoolean(true) // 内存中占1个字节

new DataInputStream(new ByteArrayInputStream(baos.toByteArray()))

.readDouble()  // 先写的先读  或者容易出现乱码

.readBoolean()

基本数据类型数据 的直接写入 与ByteArrayInutStream的结合

Print 流 只有输出流

自动flush,PrintWriter 和 PrintStream 输出操作不会抛出异常。用户通过检测错误状态获取错误信息。


PrintStream重定向

Object流 -- 序列化(标记型接口 给编译器看) 外部化 transient 保存和传递 对象状态


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

推荐阅读更多精彩内容