在Java IO中,流是一个核心的概念。流从概念上来说是一个连续的数据流。你既可以从流中读取数据,也可以往流中写数据。流与数据源或者数据流向的媒介相关联。在Java IO中流既可以是字节流(以字节为单位进行读写),也可以是字符流(以字符为单位进行读写)。

InputStream

JavaInputStream 类, java.io.InputStream,表示一个有序的 stream of bytes. 换言说,,你可以将 InputStream 作为一个有序的字节队列中读出数据,这对于从文件中读出数据或从网络中接收数据很有用。

InputStream 的子类

类方法

read()

read()可以从`InputStream中读出一个字节,读完后将返回-1

int data = inputStream.read();
while(data != -1) {
   // do something with data variable
   data = inputStream.read(); // read next byte
}

子类中可能会提供可选的read()方法,例如DataInputStream中允许你读出int, long, float, double, boolean等类型的readBoolean(), readDouble()等方法。

read(byte[])

InputStream 类还提供了两个含参数的read()方法,该方法可将InputStream中的数据读到byte[]数组中。

  • int read(byte[])
  • int read(byte[], int offset, int length)

对于read(byte[])返回值为从InpuStream中实际读取的数据长度。若InputStream中数据短于byte[]时将返回InputStream的长度并将byte[]剩余的元素重复填充InputStrem中的内容。

对于read(byte[], int offset, int length)返回值也为实际读取数据长度。offset参数为开始的位置,length为最大长度。

这两个方法也是读完后返回-1。下面是例子

InputStream inputstream = new FileInputStream("c:\\data\\input-text.txt");
byte[] data      = new byte[1024];
int    bytesRead = inputstream.read(data);
while(bytesRead != -1) {
 //doSomethingWithData(data, bytesRead);
 bytesRead = inputstream.read(data);
}
inputstream.close();

性能与BufferedInputStream

read()性能低于read(byte[]),可通过BufferedInputStream读入。

InputStream input = new BufferedInputStream(new FileInputStream("c:\\data\\input-file.txt"),
1024 * 1024        /* buffer size */
);

mark()与reset()

这两个方法在InputStream的子类中不一定支持。如果子类要支持这两个方法,需要覆写(override) markSupported()方法使其返回true

mark()可以标记一个点,然后通过reset()来回到该点。

close()

打开IOStream后一定要使用close()关闭,不然会一直占用资源。

上文介绍read(byte[])中的代码其实是不规范的,若处理中抛出了错误,inputstream.close();将不会执行。所以一般使用如下代码

try( InputStream inputstream = new FileInputStream("file.txt") ) {
   int data = inputstream.read();
   while(data != -1){
       data = inputstream.read();
  }
}

这里的try(){}结构被称为try-with-resources,是一个JDK1.7后的一个语法糖,在以前版本需要使用如下代码。

try{
   InputStream inputstream = new FileInputStream("file.txt")
   int data = inputstream.read();
   while(data != -1){
       data = inputstream.read();
  }
}
catch(Exception e){
   //deal with exception...
}
finally{
   inputstream.close();
}

finally中的代码会在try中代码成功运行或者catch到错误处理后执行。

Convert InputStream to Reader

The Java InputStream is a byte based stream of data. As you may know, the Java IO API also has a character based set of input streams called "Readers". You can convert a Java InputStream to a Java Reader using the Java InputStreamReader. You can read more about how to use the InputStreamReader by clicking the link in the previous sentence, but here is a quick example of converting an InputStream to an InputStreamReader:

InputStream inputStream       = new FileInputStream("c:\\data\\input.txt");
Reader      inputStreamReader = new InputStreamReader(inputStream);

这段看了reader先,咕咕咕,递归学习

翻译自jenkov

OutputStream

JavaOutputStream 类,java.io.OutputStream,,是Java IO API中的所有输出流的父类. OutputStream 的子类有BufferedOutputStreamFileOutputStream 等. 所有的OutputStream子类 Java IO Overview

OutputStream的子类

类方法

write(byte)

write(byte)方法可以将一个字符写入到OutputStream流中。

OutputStream outputStream = new FileOutputStream("c:\\data\\output-text.txt");
while(hasMoreData()) {
 int data = getMoreData();
 outputStream.write(data);
}
outputStream.close();

write(byte[])

OutputStream也提供了两种含参的write()方法。

  • write(byte[] bytes)
  • write(byte[] bytes, int offset, int length)

write(byte[])会将byte[]数组中的所有字符写入到OutputStream中。

write(byte[], int offset, int length)也可类比read()方法,

两个方法都会返回写入到OutputStream中的字符个数。

性能类比InputStream的read()

也可使用BufferedOutputStream 满足高性能多次写单个字符的需求。

int bufferSize = 8 * 1024;
OutputStream outputStream =
   new BufferedOutputStream(
         new FileOutputStream("c:\\data\\output-file.txt"), bufferSize);

flush()

使用flush()方法将数据输出,例如:将FileOutputStream的数据输出到文件中。

close()

InputStream一致。

Convert OutputStream to Writer

The Java OutputStream is a byte based stream. You can convert a OutputStream to a character based Writer using the Java OutputStreamWriter class. Here is an example of converting a Java OutputStream to a Writer using OutputStreamWriter:

OutputStream outputStream       = new FileOutputStream("c:\\data\\output.txt");
Writer       outputStreamWriter = new OutputStreamWriter(outputStream);

outputStreamWriter.write("Hello World");

You can read more about how to use the OutputStreamWriter including how to set the character encoding to use when converting characters to bytes in my OutputStreamWriter tutorial.

翻译自jenkov


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。