JAVA自学教程之IO流(十一)



JAVA自学教程之IO流(十一)

一、管道流

PipedInputStream 和 PipedOutPutStream

输入和输出可以直接进行连接,结合线程使用

管道流,顾名思义,写一个读一个,连成一个管子

API文档:管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream。不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。管道输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。如果向连接管道输出流提供数据字节的线程不再存在,则认为该管道已损坏

 

  1. class Input implements Runnable{
  2.     private PipedInputStream pis;
  3.     Input(PipedInputStream pis){
  4.         this.pis = pis;
  5.     }
  6.     @Override
  7.     public void run() {
  8.         try {
  9.             byte[] by = new byte[1024];
  10.             int len = pis.read(by);
  11.             String str = new String(by,0,len);
  12.             System.out.println(“str = ”+str);
  13.             pis.close();
  14.         } catch (Exception e) {
  15.             // TODO: handle exception
  16.         }
  17.     }
  18. }
  19. class Output implements Runnable{
  20.     private PipedOutputStream pos;
  21.      Output(PipedOutputStream pos) {
  22.         // TODO Auto-generated constructor stub
  23.         this.pos = pos;
  24.     }
  25.     @Override
  26.     public void run() {
  27.         // TODO Auto-generated method stub
  28.         try {
  29.             Thread.sleep(5000);
  30.             pos.write(“你好”.getBytes());//字符串转字节流
  31.         } catch (Exception e) {
  32.             // TODO: handle exception
  33.         }
  34.     }
  35. }
  36. public class Main {
  37.     public static void main(String[] args)throws IOException{
  38.         PipedInputStream pis = new PipedInputStream();
  39.         PipedOutputStream pos = new PipedOutputStream();
  40.         pis.connect(pos);//两流对接
  41.         Thread t1 = new Thread(new Input(pis));
  42.         Thread t2 = new Thread(new Output(pos));
  43.         t1.start();
  44.         t2.start();
  45.     }
  46. }

管道流应用不是很多,但是其自身很有特点

 

IO包中的其他类

操作基本类型数据的流对象—DataInputStream与DataOutputStream

操作字节数组—ByteArrayInputStream与ByteArrayOutputStream

操作字符数组—CharArrayInputStream与CharArrayOutoutStream

操作字符串—StringWriter与StringReader

 

DataInputStream与DataOutputStream

 

  1. public static void read() throws IOException {
  2.         // TODO Auto-generated method stub
  3.         DataInputStream dis = new DataInputStream(new FileInputStream(“data.txt”));
  4.         String str = dis.readUTF();
  5.         System.out.println(str);
  6.         dis.close();
  7.     }
  8.     public static void DataStreamDemo() throws IOException {
  9.         // TODO Auto-generated method stub
  10.         DataOutputStream dos = new DataOutputStream(new FileOutputStream(“data.txt”));
  11.         dos.writeUTF(“你好胖”);以与机器无关方式使用 <a target=_blank href=”">UTF-8 修改版</a>编码将一个字符串写入基础输出流。
  12.         dos.close();
  13.     }


剩下的方法和OutputStream、InputStream差不多

 

 

操作数组的流

 

源和汇都是内存。ByteArrayInputStream、ByteArrayOutputStream

ByteArrayOutputStream:此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据,关闭 ByteArrayOutputStream 无效。

 

  1. public static void ByteStreamDemo() throws IOException {
  2.     ByteArrayInputStream bis = new ByteArrayInputStream(“asdfd”.getBytes());
  3.     ByteArrayOutputStream bos = new ByteArrayOutputStream();
  4.     int len = 0;
  5.     while((len = bis.read())!=-1){
  6.         bos.write(len);
  7.     }
  8.     System.out.println(bos.toString());
  9. }


剩下的流用法和ByteArrayInputStream都是相同的

 

编码问题

编码问题无非就是文字和二进制之间的相互转换

字符串->字符数组:编码

字符数组->字符串:解码

 

  1. public static void Demo() {
  2.         String str = ”你好”;
  3.         //编码
  4.         byte[] by = str.getBytes();
  5.         for(byte b : by){
  6.             System.out.println(b);
  7.         }
  8.         //解码
  9.         String str1 = new String(by);// == new String(by,”GBK”);
  10.         System.out.println(str1);
  11.     }

 

编码编对了,有可能能成功解码

练习:按照最长字节数截取字符串
在java中字符串“abcd”与“ab你好”长度一样,都是4个字符,但是字节数不一样
定义方法,按照最大的字节数来取字节
如:“ab你好”为例,如果按照3个字节来取文字,取“ab”和半个你,半个舍弃,4个字节取“ab你”,5个字节还是“ab你”
  1. public static void main(String[] args)throws IOException{
  2.     String str = ”ab你好asdas撒旦发射的”;
  3.     int len = str.getBytes(“GBK”).length;
  4.     for(int i = 0;i<len;i++){//按照i个字节取
  5.         System.out.println(“OK : ”+Demo(str,i+1));
  6.     }
  7. }
  8. public static String Demo(String str,int len) throws IOException {
  9.     byte[] by = str.getBytes(“GBK”);
  10.     int count = 0;//记录从哪个索引开始,字节不是汉字
  11.     for(int i = len-1;i>=0;i– ){
  12.         if(by[i]<0){
  13.             count++;
  14.         }else {
  15.             break;
  16.         }
  17.     }
  18. //汉字对应2个字节,汉字的个数 = 有负字节数/2
  19. return (count & 1) == 0?new String(by,0,len):new String(by,0,len-1);
  20. }