我们讨论java输入输出一边就是两种。 一种继承InputStream和OutputStream的字节流 和 继承 Reader和 Writer 的字符流。 实际上他们基本是一样的。区别就是 字节流是
一个字节一个字节的读取。 而字符流是一个字符一个字符的读取,实际上是读取2个unicode编码的字节。 不管是字符流还是字节流,他们的核心方法都是 read或者write。
然后我们看看他们的主要的
各种实现类的对比
inputstream | outputstream | Reader | Writer | 说明 |
ByteArryInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter | 就是最基本的一个一个字节/字符的读取,实际上。基本就是用于和内存中的数据(缓冲区 )交互使用这组类 |
StringBufferInputStream | 无 | |||
FileInputStream | FileOutputStream | FileReader | FileWriter | 和文件的交互。从文件读取或者写入数据。 |
PipedInputStream | PipedOutputStream | PipedReader | PipedWriter | 多线程之间的管道交互使用这组类。 |
SequenceInputStream | 输入流的这个类是处理多个流,按顺序 一个一个读取。(直到第一个读结束,第二个才开始) | |||
FilterInputStream | FilterOutputStream |
Inputstream ,Outputstream 字节流和 Reader 和,Writer字符流之间 是通过2个适配器互相转换的。 输入流用 InputStreamReader,输出流用
OutputStreamWriter
下面简单的例子
ByteArrayOutputStream byteOutput=null;
ByteArrayInputStream byteInput=null;
FileInputStream fileInpujt=null;
FileOutputStream fileOutput=null;
CharArrayReader charArrayReader=null;
CharArrayWriter charArrayWriter=null;
FileReader fileReader=null;
FileWriter fileWriter=null;
try {
//ByteArrayOutputStream and ByteArrayInputStream
//参数是初始化时的数组个数(不设置默认好像是32)
byteOutput=new ByteArrayOutputStream(4);
byteOutput.write(new byte[]{1,2,3,4,5});
int a=6;
byteOutput.write(a);
byte b[]=byteOutput.toByteArray();
byteInput=new ByteArrayInputStream(b);
byte c[]=new byte[4];
int d;
while(( d=byteInput.read(c))!=-1)
{
System.out.println("开始读取"+d);
for(byte bb:c)
{
System.out.println(bb);
}
}
//StringBufferInputStream 已经废弃
StringBufferInputStream strInput=new StringBufferInputStream("aaaaaab");
while(( d=strInput.read(c))!=-1)
{
System.out.println("StringBufferInputStream开始读取"+d);
for(byte bb:c)
{
System.out.println(bb);
}
}
//FileInputStream
fileInpujt=new FileInputStream("D:/TEST.TEXT");
String test="";
while(( d=fileInpujt.read(c))!=-1)
{
System.out.println("FileInputStream开始读取"+d);
//test+=new String(c).substring(0, d);
}
//System.out.println(test);
//FileOutputStream
fileOutput=new FileOutputStream("D:/TEST2.TEXT");
fileOutput.write(new byte[]{12,23,34,45});
//CharArrayReader
char[] buf={'a','b','c','d'};
char[]bufout=new char[2];
charArrayReader=new CharArrayReader(buf);
while(( d=charArrayReader.read(bufout))!=-1)
{
System.out.println("CharArrayReader开始读取"+d);
for(char bb:bufout)
{
System.out.println(bb);
}
}
//charArrayWriter
charArrayWriter =new CharArrayWriter();
charArrayWriter.write('a');
charArrayWriter.write('b');
System.out.println("看看输出"+charArrayWriter.toCharArray()[0]);
//fileReader
fileReader=new FileReader("D:/TEST.TEXT");
while((d=fileReader.read(bufout))!=-1)
{
System.out.println("fileReader开始读取"+d);
for(int i=0;i<d;i++)
{
System.out.println(bufout[i]);
}
}
这个例子展示了一般的字符,字节输出输入流的用法。
而 PipedInputStream,PipedOutputStream,PipedReader,PipedWriter这4个事管道流。 负责的是线程之间的流处理。
依旧是一个例子说明一下简单用法。
public class TestPiped {
public void test()
{
PipedInputStream pis=new PipedInputStream();
PipedOutputStream pos=new PipedOutputStream();
try {
pis.connect(pos);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new ThreadOutputTest(pos).start();
new ThreadInputTest(pis).start();
}
public static void main(String[] args) {
new TestPiped().test();
}
class ThreadOutputTest extends Thread
{
PipedOutputStream pos;
public ThreadOutputTest(PipedOutputStream pos)
{
this.pos=pos;
}
@Override
public void run() {
try {
for(int i=0;i<10;i++)
{
Thread.sleep(100);
pos.write(new byte[]{1,2,3,4,5,6,7,8,9,0,11});
pos.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
//需要注意的是 如果这里不手动close掉输出流。(不过 无论啥流, 一般也不会有人不在最后close掉吧)
//最后可能会报错java.io.IOException: Write end dead 原因是线程已经结束了。但是里面还有数据。
pos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class ThreadInputTest extends Thread
{
PipedInputStream pis;
byte[] buf=new byte[11];
int a;
ThreadInputTest(PipedInputStream pis)
{
this.pis=pis;
}
@Override
public void run() {
try {
while((a=pis.read(buf))!=-1)
{
System.out.println("开始读取数据了");
for(int i=0;i<a;i++)
{
System.out.println(buf[i]);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally
{
try {
pis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
对于FilterInputStream和FilterOutputStream这2个装饰器类。 我贴上 thinking in java 中关于这2个类的描述