2019独角兽企业重金招聘Python工程师标准>>>

自己工作虽有将近三年了,也算得上是一个程序老手了,但对IO这块一直一知半解,以至于每次写IO相关的代码时,总不能随心所欲的写出自己想要的代码,每次都要百度别人的代码来借鉴。究其原因还是因为对IO这块了解的不够深入。真是如鱼刺在喉,不咽不快,这次一定要把IO这块知识咽下去。

其实对 IO 这块知识之前也有意学习过,但每次都不得要领,学了忘,用的时候再去学,一直无法理解 IO 的精髓,所以也就无法真正的领略IO了。这次学习IO总算没了之前学习的时候云里雾里的感觉。或许有些知识,真的需要时间的积累才能够理解罢!IO这块知识真的挺难理解的,很难初次学习就能对这块知识系统的理解,甚至两次、三次我们会越学越糊涂,但不要放弃,多多接触,多多看相关文章,总有那么一个时刻你会发现柳暗花明了,IO也不过如此了。

此篇文章内容多为我个人本次学习对IO的理解,可能不会太系统和太完善,不喜勿喷哦。

建议读此篇文章前,先读这篇文章:http://blog.csdn.net/wong_judy/article/details/5267911(要都三遍哦!!!)

读了上面的文章,你应该已经知道,Java IO 中一般包含两个部分:

  1. java.io包中堵塞型 IO

  2. java.nio包中的非堵塞型 IO,通常称为New IO

本篇文章主要介绍java.io包中堵塞型 IO

打开你的java.io包你可以看到Java的IO包含大量的类和接口(JDK1.6中包含83个类或者接口),如此众多的类和接口似乎无从下手。下面就将IO简单地分类。

Java的IO主要包含三个部分:

  1. 流式部分 -- IO 的主体部分

  2. 非流式部分 -- 主要包含一些辅助流式部分的类,如:File类、RandomAccessFile类和FileDescriptor等类

  3. 文件读取部分的与安全相关的类,如:SerializablePermission类。以及与本地操作系统相关的文件系统的类,如:FileSystem类和Win32FileSystem类和WinNTFileSystem类

其中“流式部分”又可以概括为:两个对应一个桥梁。两个对应指:

  1. 字节流(Byte Stream)和字符流(Char Stream)的对应

  2. 输入和输出的对应

一个桥梁指:从字节流到字符流的桥梁。对应于输入和输出为InputStreamReader和OutputStreamWriter。

在流的具体类中又可以具体分为:

  1. 介质流(Media Stream或者称为原始流Raw Stream)

    -- 主要指一些基本的流,他们主要负责从具体的介质上读取数据。

    如:从文件、内存缓冲区(Byte数组、Char数组、StringBuffer对象)等,读取数据;

  2. 过滤流(Filter Stream)

    -- 主要指所有FilterInputStream/FilterOutputStream和FilterReader/FilterWriter的子类,主要是对其包装的类进行某些特定的处理,如:缓存等。

    -- 无法单独使用,必须配合其他的一些输入输出流使用,被包装后的对象具有过滤流提供的功能如:被BufferedInputStream包装后对象具有缓存的功能,被DataInputStream包装后的对象具有读取基本数据类型的功能

上面这段的内容来自之前提到的文章,个人觉得总结的十分经典,就直接”拿来主义”了,建议上面的内容也都三遍哦。

实践是检验理论的唯一标准,编码更是如此,上面提到的模糊的概念你可能不甚理解,下面我们结合具体场景来看一下。以 Java IO 中的 字节流 中的 输入流 来具体讲解一下。

我们先来看一张图(网上找来的一张图,经测试发现并不存在ByteArrayReader这个类,图中已标红),这是java io 比较基本的一些处理流,你现在只需要看IO流-->字节流-->InputStream的那部分,结合上面的内容你应该至少知道哪些是介质流?哪些是过滤流?介质流是用来干嘛的?输入流是用来干嘛的?(不知道的话回到上面再读一遍吧)

是的,除了 ObjectInputStream 和 FilterInputStream 下的三个类,其余全是介质流,前面说过了,介质流是主要负责从具体的“介质”上读取数据的,其中“介质”可以是文件、图片、Byte数组、String对象,StringBuffer对象等。从不同“介质”上读取数据,采用的流也不相同。例如:从byte数组中读取数据到流,很显然我们知道应该用 ByteArrayInputStream。同理,从文件中读取数据,我们应该用FileInputStream。

下面我们结合上面的图,依次展示和讲解一下这些流的具体用法。

介质流

  • ByteArrayInputStream。

    我们读取一个byte数组,然后依次打印数组中的成员对应的ascii码。很显然,从byte数组中读取数据,我们应该用ByteArrayInputStream,将数组读取到流中以后,我们就能够以操作流的方式来操作byte数组了。

byte[] b = new byte[] {'j', 'a', 'v', 'a', 'i', 'o'};
ByteArrayInputStream bis = new ByteArrayInputStream(b);
int c;
// read()方法返回int类型0-255之间的数字。读取流结束返回-1
// 想想为什么返回 0-255?
while ((c = bis.read()) != -1) {System.out.println(c);
}

我们知道,计算机的最小存储单位是字节(byte),因此任何类型的数据(图片,文件,英文字符,汉字)都可以用连续的         字节(byte)来表示。任意一个英文字符,用一个字节(byte)即可表示,汉字需要两个字节(byte),一个图片或文件可以            由若干个连续的字节(byte)表示。在计算机中一个字节(byte)可以存储8位二进制数。换算为十进制,范围就是0-255

  • StringBufferInputStream。

    其用法和ByteArrayInputStream类似,不再演示。StringBufferInputStream已经被@Deprecated,原因是StringBufferInputStream不应该属于字节流,推荐使用StringReader。

  • SequenceInputStream 。

    将2个或者多个InputStream 对象转变为一个InputStream,和你想象的一样,SequenceInputStream的构造函数中可以传入两个InputStream,也可以传入一个Enumeration集合

byte[] java = new byte[]{'j', 'a', 'v', 'a'};
byte[] io = new byte[]{'i', 'o'};
ByteArrayInputStream bais1 = new ByteArrayInputStream(java);
ByteArrayInputStream bais2 = new ByteArrayInputStream(io);
SequenceInputStream sis = new SequenceInputStream(bais1, bais2);
int t;
while ((t = sis.read()) != -1) {System.out.println(t);
}
  • PipedInputStream

    一般和PipedOutputStream配合使用,读取从对应PipedOutputStream写入的数据。在流中实现了管道的概念。

PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream();
pis.connect(pos);
String pipedStr = "Hi, PipedInputStream and PipedOutputStream";
// 管道输出流写出字节
pos.write(pipedStr.getBytes());int t;
// 相应管道输入流进行读取
while ((t = pis.read()) != -1) {System.out.print((char)t);
}
pis.close();
pos.close();

这是管道流最基本的应用。利用管道流还可以实现线程间的通信。我们做这样一个应用:启动两个线程,一个线程负责           发送数据,一个线程负责接收数据。

// Sender.java 文件
public class Sender implements Runnable {PipedOutputStream out = new PipedOutputStream();/*** PipedOutputStream 和 PipedInputStream 要配对使用,双方进行连接后,write的数据才能被read到* 故在此返回 PipedOutputStream 对象*/public PipedOutputStream getPipedOutputStream() {return out;}@Overridepublic void run() {String str = "hi, pipedStream in thread";try {for (byte b : str.getBytes()) {out.write((char)b);System.out.println("send --> " + (char)b);Thread.sleep(500);}out.close();} catch (Exception e) {e.printStackTrace();}}
}
// Receiver.java
public class Receiver implements Runnable {PipedInputStream in = new PipedInputStream();public PipedInputStream getPipedInputStream() {return in;}@Overridepublic void run() {int t;try {while ((t = in.read()) != -1) {System.out.println("receive --> " + (char)t);Thread.sleep(300);}} catch (Exception e) {e.printStackTrace();}}
}
// 运行此main方法可以看出运行结果
public class PipedStream4Thread {public static void main(String[] args) throws Exception {Sender sender = new Sender();Receiver receiver = new Receiver();PipedOutputStream out = sender.getPipedOutputStream();PipedInputStream in = receiver.getPipedInputStream();in.connect(out);new Thread(sender).start();new Thread(receiver).start();}
}
  • FileInputStream

    从名称就可以看出,它是用来把文件转换为流的。

public class FileInputStreamTest {public static void main(String[] args) throws Exception {// 不指定具体路径是指当前项目跟路径下FileInputStream fis = new FileInputStream("file");byte[] buf = new byte[4];int bLen = buf.length;int t;// 想想read(buf, 0, bLen)和read()方法的区别?while ((t = fis.read(buf, 0, bLen)) != -1) {// 主意new String(buf, 0, t)一定要带 0,t 参数// 自己想想为什么吧 System.out.print(new String(buf, 0, t));}fis.close();}/*** 这里使用的是read(byte b[], int off, int len)方法进行文件字节读取,没有使用read()方法。* * read()方法每读取一个字节就要进行一次本地磁盘IO* read(byte b[], int off, int len)方法每次从本地磁盘文件中读取bLen个字节。有效的减少了程序访问本地磁盘的次数,提高了效率,* 其中bLen是b[]数组的长度。读取的字节数组会被放入b[]中,放在b[]中第off个位置先后的len个位置中* */}

至此,介质流已经介绍完了,实际应用中我们应该根据从不同介质读取数据,而使用相应的介质流。

下面我们来看过滤流。前面说过,过滤流必须配合其他的一些输入输出流使用,被包装后的对象具有过滤流提供的功能。

戳我继续:http://my.oschina.net/ironwill/blog/519398

转载于:https://my.oschina.net/ironwill/blog/519238

Java IO 之 介质流相关推荐

  1. Java IO: 其他字符流(下)

    转载自   Java IO: 其他字符流(下) 作者: Jakob Jenkov 译者: 李璟(jlee381344197@gmail.com) 本小节会简要概括Java IO中的PushbackRe ...

  2. Java——IO(打印流)

    1,打印字节流(PrintStream)的概述: 打印流可以很方便的将对象的toString()结果输出并且自动加上换行,而且可以使用自动刷出的模式 System.out就是一个PrintStream ...

  3. java IO(输入输出) 字符流

    //读取文件中的字符 package zhi_jie_liu;import java.io.*;public class Example08 {public static void main(Stri ...

  4. 系统学习 Java IO (六)----管道流 PipedInputStream/PipedOutputStream

    目录:系统学习 Java IO---- 目录,概览 PipedInputStream 类使得可以作为字节流读取管道的内容. 管道是同一 JVM 内的线程之间的通信通道. 使用两个已连接的管道流时,要为 ...

  5. java io异常处理_IO流异常处理

    import java.io.File; import java.io.FileOutputStream; import java.io.IOException; /* *IO流异常处理 *try c ...

  6. java IO之 序列流 集合对象Properties 打印流 流对象

    序列流 也称为合并流. SequenceInputStream 序列流,对多个流进行合并. SequenceInputStream 表示其他输入流的逻辑串联.它从输入流的有序集合开始,并从 第一个输入 ...

  7. java io 字节流 字符流

    1.流的概念 在程序中,所有的数据都是以流的形式进行传输和保存的,当程序需要数据的时候要使用输入流读取数据,而当程序需要保存数据时要使用输出流写数据 2.字节流和字符流 字节流:处理单元为1个字节,操 ...

  8. Java IO 之 管道流 原理分析

    概述 管道流是用来在多个线程之间进行信息传递的Java流. 管道流分为字节流管道流和字符管道流. 字节管道流:PipedOutputStream 和 PipedInputStream. 字符管道流:P ...

  9. java缓存流速度与硬盘_系统学习 Java IO (九)----缓冲流 BufferedInputStream/BufferedOutputStream...

    BufferedInputStream BufferedInputStream 类为输入流提供缓冲. 缓冲可以加快IO的速度. BufferedInputStream 不是一次从网络或磁盘读取一个字节 ...

最新文章

  1. 汪卫华院士:无序中找有序 复杂中寻规律
  2. maven 的依赖传递
  3. python udp client
  4. linux如何取文件列名,Linux_根据表名和索引获取需要的列名的存储过程,复制代码 代码如下: create proc p - phpStudy...
  5. 七十二、Vuex实现双父组件数据共享、localStorage、mapActions和keep-alive
  6. 小米3显示sim卡无服务器,小米手机无服务怎么解决
  7. wps流程图怎么不能添加文字_windows不能访问共享文件夹,不能添加共享打印机时,怎么解决呢...
  8. linux下用c语言写黄金矿工,C语言写的黄金矿工O(∩_∩)O---初稿,能玩了
  9. C#技术分享【PDF转换成图片——11种方案】
  10. Ubuntu20.04 electron ssr配置完不好用可能的原因
  11. ​以太网的发展历史、演化过程以及工作基理
  12. ps快速抠头发-庞姿姿
  13. CS5序列号文件,以后就不用担心序列号了
  14. 窗口函数 (转) rows between unbounded preceding and current row
  15. Altium Designer之4层板基本规则设置
  16. mysql授权不管用_MySQL_MySQL授权问题总结,我用localhost的root帐号不能连 - phpStudy...
  17. 阿里云服务器部署javaweb
  18. Python 数据可视化的 3 大步骤,你知道吗?
  19. mac系统下不用u盘怎么装win7系统
  20. 程序员转行中,深入研究一下产品经理岗,有兴趣的一起来学习进步吧!

热门文章

  1. 【Linux】【Services】【Package】编译安装
  2. ios开发-Object-C可变参数函数
  3. wp7检测网络是否可用以及网络开启简单代码段
  4. SQLServer如何取得随机获取的数据库记录
  5. ROS 图像相关的命令与应用
  6. python有什么证可以考1002python有什么证可以考_离python二级考还有十几天,吓的我赶紧买了本python教程...
  7. springboot springmvc mybatis_深圳嘉华学校之springboot实战教程
  8. linux 内核参数优化 mysql_Linux记录-mysql参数优化
  9. mysql in和or扫描全表_MySQL对OR条件查询不支持优化,会进行全表扫描
  10. html5光标进去默认值消失,html点击input没有出现光标怎么办