zoukankan      html  css  js  c++  java
  • 字节流InputStream/OutputStream

    字节流InputStream/OutputStream

    本篇将对JAVA I/O流中的字节流InputStream/OutputStream做个简单的概括:

    总得来说,每个字节流类都有一个对应的用途,如下:

    • ByteArrayInputStream/ByteArrayOutputStream     //字节数组相关
    • FileInputStream/FileOutputStream                        //文件操作相关
    • PipedOutputStream/PipedInputStream                  //线程间通信(管道)    
    • BufferedInputStream/BufferedOutputStream         //装饰其它字节流,增加缓冲功能                 
    • FilterInputStream/FilterOutputStream                    //装饰其它字节流,增加一些过滤处理
    • PushbackInputStream                                           //装饰其它字节流,增加回退读取功能            
    • DataOutputStream/DataInputStream                     //装饰其它字节流,增加对JAVA基本数据类型的读取/写入功能        
    • PrintStream                                                           //装饰其它字节流,增加格式化数据写入功能
    • ObjectInputStream/ObjectOutputStream               //装饰其它字节流,增加对象的序列化,以字节形式读取/写入到本地文件
    • SequenceInputStream                                           //以串行形式连接若干字节输入流

    再看下字节流InputStream/OutputStream的组成结构,如下图

    接下来逐个介绍;

    ByteArrayInputStream/ByteArrayOutputStream

    简单地说,就是字节数组与字节输入输出流之间的各种转换,举个例子如下:

    package io;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    public class IOTest {
    
        public static void main(String[] args) throws IOException {
            //内存中的字节数组
            byte[] bArr = new byte[]{1,2,3};
            
            //字节输入流
            InputStream is = new ByteArrayInputStream(bArr);
            //字节输出流
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
    
            byte[] bff = new byte[3];
            //从输入流中读取字节
            is.read(bff,0,3);
            System.out.println(bff[0] + "," + bff[1] + "," + bff[2]);
    
            //往字节输出流中写入字节数组
            bos.write(bff);
            //从输出流中获取字节数组
            byte[] bArryFromOs = bos.toByteArray();
            System.out.println(bArryFromOs[0] + "," + bArryFromOs[1] + "," + bArryFromOs[2]);
        
            is.close();
    bos.close(); } }

    FileInputStream/FileOutputStream

    可以用FileInputStream/FileOutputStream对文件进行写入及读取,如下代码,可以实现文件的复制:

    package io;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    public class IOTest {
    
        public static void main(String[] args) throws IOException {
    
            // 字节输入流
            InputStream is = new FileInputStream("C:\test.jpg");
            // 字节输出流
            OutputStream os = new FileOutputStream("C:\copy_test.jpg", false);
    
            int bTmp = -1;
            while ((bTmp = is.read()) != -1) {
                os.write(bTmp);
            }
            is.close();
            os.close();
        }
    }

    PipedOutputStream/PipedInputStream

    可用于同一个JVM中的两个线程间通信,字节流传输,举个例子:

    package io;
    
    import java.io.IOException;
    import java.io.PipedInputStream;
    import java.io.PipedOutputStream;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class IOTest {
    
        public static void main(String[] args) throws IOException {
    
            
            final PipedOutputStream pos = new PipedOutputStream();
            final PipedInputStream pis = new PipedInputStream(pos);
    
            ExecutorService es = Executors.newFixedThreadPool(2);
    
            es.execute(new Runnable() {
    
                @Override
                public void run() {
                    try {
                        byte[] bArr = new byte[]{1,2,3};
                        pos.write(bArr);
                        pos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
    
            es.execute(new Runnable() {
    
                @Override
                public void run() {
    
                    byte[] bArr = new byte[3];
                    try {
                        // 会导致线程阻塞
                        pis.read(bArr, 0, 3);
                        pis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    System.out.println(bArr[0] + "," + bArr[1] + "," + bArr[2]);
                    
                }
            });
        }
    }

    BufferedInputStream/BufferedOutputStream

    带缓冲区的字节流,装饰器模式在jdk中的一个应用,可用于装饰其它字节流;

    一次读取/写入一大块字节到缓冲区,避免每次频繁访问外部媒介,提高性能;

    下面是一个例子:

    package io;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class IOTest {
    
        public static void main(String[] args) throws IOException {
    
            // 字节输入流
            BufferedInputStream is = new BufferedInputStream(new FileInputStream("C:\test.jpg"), 10 * 1024);
            // 字节输出流
            BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream("C:\copy_test.jpg", false));
    
            int bTmp = -1;
            while ((bTmp = is.read()) != -1) {
                os.write(bTmp);
            }
    
            is.close();
            os.close();
        }
    }

    FilterInputStream/FilterOutputStream

    可装饰其它字节流,实现自定义过滤字节流的基类,基本上是简单的覆盖了InputStream/OutputStream中的方法,意义不是很大;

    PushbackInputStream

    可装饰其它字节输入流,增加的功能是是回退读取,如下例子:

    package io;
    
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.PushbackInputStream;
    
    public class IOTest {
    
        public static void main(String[] args) throws IOException {
    
            byte[] bArr = new byte[] { 1, 2, 3 };
            
            // 字节输入流
            PushbackInputStream pis = new PushbackInputStream(new ByteArrayInputStream(bArr));
    
            System.out.println(pis.read());
            System.out.println(pis.read());
            // 回退
            pis.unread(1);
            System.out.println(pis.read());
    
            pis.close();
    
        }
    }

    DataOutputStream/DataInputStream

    可装饰其它字节输入流,增加从输入流中读取Java基本类型数据的功能;

    举个例子:

    package io;
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class IOTest {
    
        public static void main(String[] args) throws IOException {
            // 字节输入流
            
            DataOutputStream dos = new DataOutputStream(new FileOutputStream("C:\data.data"));
            DataInputStream dis = new DataInputStream(new FileInputStream("C:\data.data"));
            
            dos.writeDouble(2.0235);
            dos.writeInt(520);
            dos.flush();
            
            System.out.println(dis.readDouble());
            System.out.println(dis.readInt());
    
            dos.close();
            dis.close();
    
        }
    }

    PrintStream

    PrintStream可以装饰其它字节输出流,允许将格式化数据写入到字节输出流中,如下示例,将格式化数据写到控制台上;

    package io;
    
    import java.io.IOException;
    import java.io.PrintStream;
    
    public class IOTest {
    
        public static void main(String[] args) throws IOException {
            // 字节输出流
            PrintStream ps = System.out;
            //输出格式化数据
            ps.println("hello");
            ps.printf("%5d
    ", 101);
            ps.write('2');
            
            ps.close();
    
        }
    }

    ObjectInputStream/ObjectOutputStream

    可以装饰其它字节输出流,主要用于对象序列化,可以将一个对象以字节流的形式写入/读取到本地文件中,如下例子:

    package io;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    class Dog implements Serializable {
        /**
         * 
         */
        private static final long serialVersionUID = -3581113588185842098L;
        private int age;
    
        public Dog(int age) {
            this.age = age;
        }
    
        public int getAge() {
            return this.age;
        }
    }
    
    public class IOTest {
    
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("C:\object.data"));
            ObjectInputStream input = new ObjectInputStream(new FileInputStream("C:\object.data"));
    
            Dog dog = new Dog(2);
    
            output.writeObject(dog); 
            output.flush();
    
            Dog obj = (Dog) input.readObject();
            System.out.println(obj.getAge());
    
            output.close();
            input.close();
        }
    }

    SequenceInputStream

    把一个或者多个InputStream串行连接起来,第一个流读完,继续读取第二个流,如下例子

    package io;
    
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.SequenceInputStream;
    
    public class IOTest {
    
        public static void main(String[] args) throws IOException {
            // 内存中的字节数组
            byte[] bArr = new byte[] { 1, 2, 3 };
            byte[] bArr2 = new byte[] { 4, 5, 6 };
    
            // 字节输入流
            InputStream is = new ByteArrayInputStream(bArr);
            // 字节输入流
            InputStream is2 = new ByteArrayInputStream(bArr2);
            // 字节输入流,连接以上两个流
            SequenceInputStream sis = new SequenceInputStream(is, is2);
    
            byte[] bff = new byte[3];
            // 从输入流中读取字节
            sis.read(bff, 0, 3);
            System.out.println(bff[0] + "," + bff[1] + "," + bff[2]);
            // 会从第二个字节流读取数据
            sis.read(bff, 0, 3);
            System.out.println(bff[0] + "," + bff[1] + "," + bff[2]);
    
            is.close();
            is2.close();
            sis.close();
        }
    }
  • 相关阅读:
    SQL基本之增删查改操作
    【转】C++静态库与动态库
    使用日志记录功能查看PHP扩展的执行过程
    写一个打印日志的函数
    写一个CGI程序并运行
    gcc及其选项详解 【转载】
    Linux下gcc编译生成动态链接库*.so文件并调用它【转载】
    Laravel框架开发规范-修订版
    Laravel框架开发规范-修订前期版
    基本语句优化10个原则
  • 原文地址:https://www.cnblogs.com/chenpi/p/5367823.html
Copyright © 2011-2022 走看看