Java I/O全文摘要(一)基本I/O,介绍

15 篇文章 0 订阅
12 篇文章 0 订阅

本文摘要自Java I/O一书,选取中间精炼简单的部分,译成中文,并书写成文章。


1.什么是流? What is Stream?

A stream is an ordered sequence of bytes of indeterminate length.

流是长度不确定的字节序列.

输入流将其他通用的外部目标移入Java程序,而输出流则是将Java程序中的数据移到外部。

输入到Java程序的来源是多样的,输出流也有多种目的地。

所有的输入输出流在形式上是简单的,你使用相同的类和相同的方法来进行操作。


2.流来自什么地方?

最简单的输入流莫过于 System.in

输出流则是 System.out System.err


当然还有 文件流,网络流,管道流


3.大体有一些什么类呢?

最基本的:java.io.InputStream java.io.OutputStream


此外,还有(不必记住它们,后面会介绍)

BufferedInputStream

BufferedOutputStream

ByteArrayInputStream

ByteArrayOutputStream

DataInputStream

DataOutputStream

FileInputStream

FileOutputStream

FilterInputStream

FilterOutputStream

ObjectInputStream

ObjectOutputStream

PipedInputStream

PipedOutputStream

PrintStream

PushbackInputStream

SequenceInputStream


还有来自java.util.zip,java.util.jar包与压缩相关的流;

来自java.security和JCE的摘要和安全方面相关的流。


4.数值对象

由于InputStream 和OutputStream是以byte(字节)为单位进行读取写入的;

而Readers和Writers是以character(字符)为单位进行读写操作的,

所以必须理解Java是如何处理基本类型,以及如何将其中一个转化为另一个。


int 4byte ,big-endian(大端字节序)

BE:将高序字节存储在起始地址

例如:0x4321

0x4000 0x4001 0x4002 0x4003

     4          3          2           1

byte :8bit

但是,由于任何 int以下数字的加法都将转化为int,所以直接使用byte并非最佳实践。

byte b1 = 22;
byte b2 = 23;
byte b3 = b1 + b2;//error!need obvious cast

5.输入输出基本方法

处于这样的原因,所以输入流虽然是对byte进行读操作,但是返回值确实int

public abstract int read( ) throws IOException
使用0~255来表示读到的数据,使用-1表示流已经到达末尾。

而在输出流,也可以看到这样的实现:

public abstract void write(int b) throws IOException
注意,传入的数据b只运行0~255,否则将截取

使用b = b & 0x000000FF;

此外,允许读取数组:

public int read(byte[] data) throws IOException
public int read(byte[] data, int offset, int length) throws IOException

一批次读取多个byte能显著的提高效率,这是因为

单一的byte任然需要在JVM中占据4byte空间,但bytes数组占据了它实际所需空间的总和。

虽然byte只能保存-128~127,但是下面这个方法用于有符号型到无符号型的转化:

int unsignedByte = signedByte >= 0 ? signedByte : 256 + signedByte;

6.字符数据

Java程序需要进行处理的内容:数字是一部分,而文本是另一部分。

而字符码是和编码有关的,例如在Ascii中将A编码成65,B编码成66;不同的编码,不同的结果。

Java支持多种语言的多种编码方式,

Java内置使用Unicode字符集,它是Latin-1字符集的超集。


7. ASCII和Latin-1

American Standard Code for Information Interchange, is a 7-bit character set

Latin-1, is an 8-bit character set that's a strict superset of ASCII

Latin-1相当于在标准ASCII的基础上增加了1bit,然后新增了128个字符,用于表示拉丁文和一些图形


8. Unicode

Latin-1能够满足西欧国家的使用,但是却满足不了Cyrillic, Greek, Arabic, Hebrew, or Devanagari,

而中国,日本这类象形文字的就更不可能了,所以开发了Unicode。

它有100万种可能,能够满足绝大多数国家语言的需求。

[重要]Unicode只是一个字符集,而不是一种编码方式。

也就是说,虽然Unicode规定了A编码成65,但并没有说是用1个字节,2个字节还是4个字节,这就导致了多种可能。

但实际上最常用的编码方式还是UTF-8, UTF-16, and UTF-32。

UTF-32是最幼稚的编码方式,简单的使用4byte代表所有的数据。

UTF-16,使用2字节来表示常用字符,使用4字节来表示中文,音乐数学符号,和其他已经死亡的语言。

UTF-8,最高效的方式,1字节表示ASCII,2字节表示其他字母表,3~4字节来表示亚洲语系。


除了上面介绍的三种ASCII,Latin-1,Unicode以外,还有很多的字符集。


9. char数据类型

在Java中,文本主要由char,char array,String组成。

char由2个字节构成,使用默认的UTF-16进行编码。

[注意]String.getBytes()将会根据字符集来返回byte数目。


10. Reader和Writers

输入输出流是byte-based;而读写器是character-based,它依据不同的编码集而具有不同位宽。

例如ASCII 和 Latin-1 使用 1-byte characters. UTF-32 使用 4-byte characters. UTF-8 使用可变宽度的characters

java.io.Reader和java.io.Writer是顶层的抽象类

包括各8个读写器:

BufferedReader
BufferedWriter
CharArrayReader
CharArrayWriter
FileReader
FileWriter
FilterReader
FilterWriter
InputStreamReader
LineNumberReader
OutputStreamWriter
PipedReader
PipedWriter
PrintWriter
PushbackReader
StringReader
StringWriter全部位于java.io包中。

对比与流,则是将其中的byte替换成了char

例如在OutputStream中,其中一个写方法为

public void write(byte[] data) throws IOException
则在Writer中,变为了

public void write(char[] data) throws IOException
,但是 Writer提供了两个额外的方法,用于操作字符串。

public void write(String s) throws IOException
public void write(String s, int offset, int length) throws IOException

11. 缓冲与通道 Buffers and Channels

传统的流会阻塞进程,直到流结束,而过去的处理方式是起一个单独的线程来处理它。

而线程的创建和管理都需要大量工作。

Java1.4中引入了非阻塞I/O。

流只是一个代表,实际工作都在buffer和channel中完成了;

可多通道读取写入流,这样一个线程就处理多个通道的信息。

通道和缓冲还可用于内存映射的I/O,文件被当做大的内存块来使用。

被映射的文件可以使用诸如

int x = file.getInt(1067)来的形式读取,或者

file.putInt(x, 1067) 形式来写入。

通道和缓冲比流和字节要复杂,但是对于特定的应用程序,这些复杂度是值得的。


12. 普遍存在的异常 The Ubiquitous IOException

自从计算机运转开始,输入输出就不可靠。

几乎每一个输入输出流都将抛出 IOException,它是一个受检异常。

所以,你使用这些流时,要么抛出异常,要么try catch 它。唯一的例外是PrintStream and PrintWriter。

IOException有很多子类,用于表示特定的I/O异常。


13. 控制台 System.out, System.in, and System.err

System.out与 C或者Unix中的stdout一致

System.err通常没啥用,debug的时候可能会用到

System.in标准输入

这几个流都可重定向:

public static void setIn(InputStream in)
public static void setOut(PrintStream out)
public static void setErr(PrintStream err)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值