Java IO:面向流、同步、阻塞式IO(BIO)

来源:互联网 发布:奥鹏教师网络研修社区 编辑:程序博客网 时间:2024/05/06 15:22

转载请注明出处:jiq•钦's technical Blog 

备注:阅读此文之前,建议先看我这篇博文了解阻塞式IO和非阻塞式IO的基本概念。


JAVA BIO是面向流(字节流、字符流)的,即从流中一次读取一个或者多个字节,读取和写入时都需要同步阻塞直至完成。

一、流(Stream)

1、字节流

输入(InputStream)

介质流

FileInputStream

从文件中读取信息

PipedInputStream

产生用于写入相关PipedOutputStream的数据,实现“管道化”概念

ByteArrayInputStream

允许将内存缓冲区当做InputStream使用

处理流

SequenceInputStream

将两个或多个InputStream转换为单个InputStream

ObjectInputStream

对象输入流

FilterInputStream子类

 

BufferedInputStream

防止每次读取时都进行实际写操作,代表“使用缓冲区”

DataInputStream

与DataOutputStream配合使用,可以按照可移植的方式从流读取基本数据类型(int、char、long等)

LineNumberInputStream

 

PushbackInputStream

 

 

输出(OutputStream)

介质流

FileOutputStream

用于将信息写至文件

PipedOutputStream

任何写入其中的信息都会自动作为相关PipedInputStream的输出,实现“管道化”概念

ByteArrayOutputStream

在内存中创建缓冲区,所有送往“流”的数据都放置在此缓冲区

处理流

ObjectOutputStream

对象输出流

FilterOutputStream子类

 

BufferedOutputStream

避免每次发送数据时都要进行实际的写操作,代表“使用缓冲区”

DataOutputStream

与DataInputStream配合使用,按照可移植的方式向流中写入基本类型数据(int、char、long等)

PrintStream

用于产生格式化输出,DataOutputStream处理数据的存储,PrintStream处理显示


2、字符流

输入(Reader)

介质流

FileReader

FileInputStream的对应

CharArrayReader

ByteArrayInputStream的对应

PipedReader

PipedInputStream的对应

处理流

BufferedReader

BufferedInputStream的对应

InputStreamReader

用于将InputStream转换为Reader

 

输出(Writer)

介质流

FileWriter

FileOuputStream的对应

CharArrayWriter

ByteArrayOutputStream的对应

PipedWriter

PipedOutputStream的对应

处理流

BufferedWriter

BufferedOutputStream的对应

OutputStreamWriter

用于将OutputStream转换为Writer

 

字节流与字符流:

(1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

(2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

(3)字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作流。比如用两种方式分别写文件,但是写完之后不关闭流,最后你可以发现字节流写的文件有内容、而字符流没有。

(4)设计Reader/Writer继承层次主要是为了国际化,字节流仅支持8位的读写,不能很好处理16位的Unicode字符,java本身的char是16位的,添加字符流就是为了在所有IO操作中都支持Unicode。


建议:

在处理字符、尤其是中文文本时优先选择字符流!

在处理其它格式如图片、音频等文件时只能采用字节流!

由此基本可以认为,能用字符流就用,一旦无法满足需求,再考虑字节流!!!

 

装饰器设计模式(Decorator):

上面的流中,字节流和字符流各自内部的“处理流”可以包装其他“处理流”和“介质流”,而InputStreamReader和OutputStreamWriter可以包装字节流,提供了字节流到字符流的转换功能。


二、输入输出(IO)

1、文件IO

字节流:

public static void main(String[] args)throws IOException {      String fileName="D:"+File.separator+"hello.txt";      File f=new File(fileName);      InputStream in=new FileInputStream(f);      byte[] b=new byte[1024];      int count =0;      int temp=0;      while((temp=in.read())!=(-1)){          b[count++]=(byte)temp;      }      in.close();      System.out.println(new String(b));    }

字符流:

public static void main(String[] args)throws IOException {      String fileName="D:"+File.separator+"hello.txt";      File f=new File(fileName);      char[] ch=new char[100];      Reader read=new FileReader(f);      int temp=0;       int count=0;      while((temp=read.read())!=(-1)){          ch[count++]=(char)temp;      }      read.close();      System.out.println("内容为"+new String(ch,0,count));    }

2、内存IO

public static void main(Stringargs[])throws IOException {         Stringstr = “Hello,jiyiqin”;ByteArrayInputStreambInput = new ByteArrayInputStream(str.getBytes());System.out.println("Convertingcharacters to Upper case " );for(int y = 0 ;y < 1; y++ ) {while(( c= bInput.read())!= -1) {System.out.println(Character.toUpperCase((char)c));}bInput.reset();}}

3、管道IO

import java.io.InputStream;import java.io.OutputStream;import java.io.PipedInputStream;import java.io.PipedOutputStream; public class PipedInputStreamTest {   public static void main(String args[]) {       PipedInputStream input = new PipedInputStream();       PipedOutputStream output = new PipedOutputStream();       try {           output.connect(input);           new Thread(new OutputstreamRunnable(output)).start();           new Thread(new InputstreamRunnable(input)).start();       } catch (Exception e) {           e.printStackTrace();       }    }} //输出管道流线程class OutputstreamRunnable implementsRunnable {   private OutputStream out;   public OutputstreamRunnable(OutputStream output) {       this.out = output;    }   @Override   public void run() {       String str = "hello pipe";       try {           out.write(str.getBytes());           out.flush();           out.close();       } catch (Exception e) {           e.printStackTrace();       }    }} //输入管道流线程class InputstreamRunnable implementsRunnable {   private InputStream in;   public InputstreamRunnable(InputStream in) {       this.in = in;    }   @Override   public void run() {       byte[] bs = new byte[1024];       int len = -1;       try {           if ((len = in.read(bs)) != -1) {                System.out.println(newString(bs, 0, len));           }       } catch (Exception e) {           e.printStackTrace();       }    }}

4、网络IO

即常说的Java套接字(Socket)编程,这是阻塞式的Java网络IO。

服务端代码

public class Server {        public static void main(String args[]) throws IOException {       int port = 8888;       ServerSocket server = new ServerSocket(port);       Socket socket = server.accept();       Reader reader = new InputStreamReader(socket.getInputStream());        char chars[] = new char[64];        int len;        StringBuilder sb = new StringBuilder();        while ((len=reader.read(chars)) != -1) {           sb.append(new String(chars, 0, len));        }        System.out.println("from client: " + sb);        reader.close();        socket.close();        server.close();     }  }  

 客户端代码

public class Client {        public static void main(String args[]) throws Exception {       String host = "127.0.0.1";      int port = 8888;      Socket client = new Socket(host, port);      Writer writer = new OutputStreamWriter(client.getOutputStream());        writer.write("Hello Server.");        writer.flush();      writer.close();        client.close();     }  }  

1 0
原创粉丝点击