JAVA 学习 【I/O 基础】

来源:互联网 发布:网络教学app有哪些 编辑:程序博客网 时间:2024/05/21 10:54

JAVA API 学习 【I/O】

在学习之前需要先搞懂在I/O中很重要的概念就是字节流 。在java的I/O中与字节流相关的class的命名规则全部为xxxStream(如:InputStream,OutputStream)。字节流顾名思义,就是字节组成的流。为什么要着重讲这个呢。因为在java 的 I/O接口中还存在一种字符流 的概念。字符流是基于字节流,并且专门用来处理文本数据。使用字符流可以指定编码格式,而不用手动的将字节转换成我们所需的编码。简单的来说,字符流是一种为了加快我们程序开发而在java中内置的一种基于字节流的工具。

OutputStream

OutputStream是所有输出流的超类。里面定义了所有我们使用到的方法。他实现了Closeable(AutoCloseable)和Flushable接口。一个定义了关闭缓冲区的接口,一个定义了刷新缓冲区的接口。其中特别说明的是AutoCloseable是对try(){}写法的支持,这样可以自动关闭流句柄。(实现Closeable接口的使用close()方法关闭,实现Flushable接口的使用flush()方法进行刷新缓冲区)。

输出流的write方法分为3个版本

  • write(byte[])
  • write(int)
  • write(byte[],int off,int len)

其中write(int)输出字节的核心方法。其他两个方法均是处理字节数组之后再掉用write(int)进行写入。

这里需要注意的是虽然write(int)的参数类型是int,不过它只能接受0-255(无符号字节)的值。超过这个范围的值都会被int强制转换为byte,这会引起数据的丢失(具体转换规则请看另一篇文章)。

这里有一点需要说明:因为每个TCP分片至少要包含40字节用于路由和纠错。所以如果单个包内发送的数据过少通常不是很好的做法。

InputStream

输入流河输出流类似,只是包写入write()换成了read()
输入流稍微比输出流复杂一些。它有skip()available()的概念。由于目前这两个的认识不是很全面留在这里日后补充。

他的子类主要是通过不同介质中来获取数据。特别说明TelnetInputStream隐藏在sun.net包中,不提供相关的文档,java.net中的很多函数都会返回这个stream。不过在返回类型是依然会显示为InputStream

read()方法在流没有结束,时有可能会阻塞线程等待数据到达。所以I/O最好放在单独的线程中进行操作。

read()读出的是int类型的从-128到127,而byte数组需要0-255。所以需要对越界的数值进行转化。

int i = b >=0 ?b:b+256;

read() 的参数是字节节数组的时候,read()的返回值是实际读取的字节数。

read()的参数length为0的时候,read()不会注意到流的结束而会返回0。

过滤器

过滤器分为2部分。
* 过滤器流
* 阅读器和书写器
过滤器在使用的时候要注意,只能从最后一个过滤器对数据进行操作。所以推荐以下写法以避免这个问题

DataOutputStream d = new DataOutputStream(                     new BufferedOutputStream(                     new FileOutputStream("data.txt")                     )                     );

缓冲流

缓冲在网络连接中起着重要的作用,概括来讲,缓冲就是将数据储存到一个指定的位置(缓冲流)当触发了某些事件以后(例如读取,缓冲区满了,刷新缓冲区操作)时候一次性的操作数据。

缓冲区的参数除了底层流的句柄以外,还可以设置缓冲区的大小。

  • BufferedInputStream(InputStream in)
  • BufferedInputStream(InputStream in , int bufferSize)
  • BufferedOutputStream(OutputStream in)
  • BufferedOutputStream(OutputStream in , int bufferSize)

PrintStream

数据流

数据流(DataOutputStream,DataInputStream)在提供了基础的操作的同时还提供了获取指定数据类型的的方法命名规则read/write + 数据类型名称,这里有个特例,就是unsigned类型。因为java中没有无符号类型。所以在write的时候是没有unsigned类型。

当知道流中的数据长度的时候,可以通过readFully(byte[])/readFully(byte[],int offset ,int length)进行强制读取,当数据长度不够的时候,会抛出异常。

writeUTF()ReadUTF()是配套使用。

阅读器和书写器

首先要申明:不是所有的文本都是ASCII,

阅读器的超类是java.io.Reader
书写器的超类是java.io.Writer

java内置了3个系列:
* FileReader
* FileWrite
* StringReader
* StringWriter
* CharArrayReader
* CharArrayWriter

以所列的类除了构造函数不同,使用的公共的接口。

stream和阅读器的结合

  • InputStreamReader
  • OutputStreamWriter

这两个类的第一个参数分别是InputStreamOutputstream 的句柄。第二个可选的参数是编码格式,主要的作用是为了在规定的字符编码下进行I/O操作,而程序猿不必关心编码的过程。

public String getEncoding()

获取编码格式

BufferedReaderBufferedWriter镜像BufferedInputStreamBufferedOutputStream。只是把字节数组换成了字符数组。

(PS:对于I/O的掌握还不是太好目前只是对一些重要知识点的罗列,以后会随着我对这块知识的更深的理解随时来修改)

1 0
原创粉丝点击