深入理解java I/O系统
来源:互联网 发布:傲友软件 编辑:程序博客网 时间:2024/05/02 12:52
提起JAVA I/O系统,大家会想到很多常用的类和固定用法,这些使用方式对实现读写操作很有帮助。但让我们给这些类和方法划分种类时,往往十分困难,因为他们完成的功能都类似。而且从功能角度出发,正常工作才是王道。处于好学,参照JAVA编程思想,对JAVA I/O系统梳理了一番。说的不到或不对的地方,还请看客给些积极意见!
要弄清楚I/O系统,就要了解通道和流是什么。
通道是任何能够连接到可以进行I/O操作实体的连接。
流是可操作I/O实体从一存储或操作空间到另一存储或操作空间的中间状态。
这两者之间的关系就像自来水管道和水流之间的关系,可操作I/O实体就是水源,水从自来水厂发出,通过管道流向各家各户,这之间水以水流的状态存在管道中。在I/O操作中,对实体操作要先建立通道,实体以流的方式进行转移和变化。计算机最底层以字节为单位对数据存储,因此在管道中数据是以字节流的形式传递。为适应不同语言(中文),通过上层封装,可以对字符直接操作,产生字符流。这也就是常见的InputStream、OutputStream和Reader、Writer类由来。下面就从源码层次上了解下这些类的特点。
InputStream类中我们主要关注下两个read方法,实际的读操作是由子类实现的read方法完成,InputStream类提供一个使用byte数组存储字节的read方法。OutputStream类的实现思想与之类似,底层实际的写操作使用子类中的write方法实现。
//抽象方法,用来被子类实现 public abstract int read() throws IOException; //该方法将数据源中从off开始,长度为len的数据读到b数组中 public int read(byte b[], int off, int len) throws IOException {if (b == null) { throw new NullPointerException();} else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException();} else if (len == 0) { return 0;}int c = read();if (c == -1) { return -1;}b[off] = (byte)c;int i = 1;try { for (; i < len ; i++) {c = read();if (c == -1) { break;}b[off + i] = (byte)c; }} catch (IOException ee) {}return i; }Reader类中主要方法为,由子类来实现具体方法。这里的参数是char数组类型,而不再是byte数组,这也充分说明Reader类主要是处理字符。字符和字节虽然都是8位表示,且能够进行安全转换,但人们喜欢看字符和不是转换为字节的数字。因此要让Reader类正常工作,中间还需要一个适配器,将字节转换为字符。
abstract public int read(char cbuf[], int off, int len) throws IOException;最简单的适配子InputStreamReader,该类使用装饰者模式,实现Reader的所有方法,底层再调用InputStream的实现。如何工作让我们看看他的构造函数就知道了。在类中有一个StreamDecoder类型的final变量sd,构造函数主要对他进行初始化。适配器中的所有read方法,都自然而然的转换到sd.read()上。截止到这,我们还是没看到最底层的字符与字节的转换,虽然能够想象,但还是很想看到源码中的这些操作。那就继续深耕查看下StreamDecoder类吧。
public InputStreamReader(InputStream in) {super(in); try { sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object } catch (UnsupportedEncodingException e) { // The default encoding should always be available throw new Error(e);} }StreamDecoder类的源码操作。这些真相大白了,虽然封装很多层,但原理还是一样的,只是在读取byte后将其强转为char类型,原理很简单的。
public int read(char cbuf[], int offset, int length) throws IOException {149 int off = offset;150 int len = length;151 synchronized (lock) {152 ensureOpen();153 if ((off < 0) || (off > cbuf.length) || (len < 0) ||154 ((off + len) > cbuf.length) || ((off + len) < 0)) {155 throw new IndexOutOfBoundsException();156 }157 if (len == 0)158 return 0;159 160 int n = 0;161 162 if (haveLeftoverChar) {163 // Copy the leftover char into the buffer164 cbuf[off] = leftoverChar;165 off++; len--;166 haveLeftoverChar = false;167 n = 1;168 if ((len == 0) || !implReady())169 // Return now if this is all we can produce w/o blocking170 return n;171 }172 173 if (len == 1) {174 // Treat single-character array reads just like read()175 int c = read0();176 if (c == -1)177 return (n == 0) ? -1 : n;178 cbuf[off] = (char)c;179 return n + 1;180 }181 182 return n + implRead(cbuf, off, off + len);183 }184 }到现在大家对字节流类和字符流类有了更深一层了解,使用时无外乎不同的子类之间的搭配,工作原理和上面介绍的都是一样的。具体有哪些使用方法,可以上网查找。到现在为止还有一个重要的类RandomAccessFile,它的实现思路与前两类都不同,但功能更加强大。它可以随意读取文件的某一段内容,不许要按照顺序。也可以随意的对某一段内容修改,然后写回。是一个具备读、写双向功能的类。它常与mappedbytebuffer类搭配使用,完成十分强大的工作。下一节将对其进行介绍。
0 0
- 深入理解java I/O系统
- 深入理解 java I/O
- 深入理解 java I/O
- 深入理解 java I/O
- 《深入理解计算机系统》--系统级I/O
- 【深入理解计算机系统】系统级I/O
- 深入理解JAVA I/O机制
- 《深入理解计算机系统》系统级I/O——读书笔记
- 阅读深入理解计算机系统(四)--------------- 系统级I/O
- 深入理解 I/O 概念
- 系统级I/O与标准I/O--“深入理解计算机系统”
- 深入理解JAVA I/O系列五:对象序列化
- 深入理解JAVA I/O系列四:RandomAccessFile
- Java I/O系统
- java I/O系统
- Java I/O系统
- Java I/O系统
- Java I/O系统
- 微信使用网页授权获取用户基本信息
- js实现剪切板效果复制黏贴图片
- HDU 3549 — Flow Problem 入门题
- NSUserDefaults
- C编译器剖析PDF文档及UCC编译器162.3
- 深入理解java I/O系统
- error MSB8020
- 微信判断当前用户是否关注某个公众号
- python for android 环境搭建(一)
- Exchange Server 2013 系列三:部署规划
- ssh: connect to host localhost port 22: Connection refused
- 真正理解 git fetch, git pull 以及 FETCH_HEAD
- 黑马程序员---第八篇 block与protocol
- 《算法导论》1、插入排序实现(C++)