美文网首页
Java学习——day 17

Java学习——day 17

作者: 振礼硕晨 | 来源:发表于2019-01-27 12:49 被阅读0次

    主要内容

    • 缓冲流
    • 转换流
    • 字节数组流
    • 数据流
    • 对象流

    笔记详情

    1. 缓冲流

    Java中的流可以分为节点流和处理流,节点流处于IO操作的第一线,所有的操作都必须通过他们进行。处理流可以对节点流进行其他流进行处理(提高效率或者操作灵活性)。

    缓冲流是Java中的处理流,可以用来提高性能。常见的处理流有字节处理流(BufferedInputStream、BufferedOutputStream )和字符处理流(BufferReader BufferWriter)。常用的用法如下:

    /**
     * 使用缓冲流增强功能,提高性能
     */
    import java.io.*;
    public class Demo01 {
    
        public static void main(String[] args) throws IOException {
    
            // 建立文件的联系
            File src = new File("src/testStream/1.jpg");
            File dest = new File("src/testStream/2.jpg");
    
            // 缓冲流,嵌套在文件流的外面,提高性能
            InputStream is = new BufferedInputStream(new FileInputStream(src));
            OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));
            
            byte[] data = new byte[10];       // 每次读取和写入的字节大小
            int len;
    
            // 不断读取和写入
            while ((len = is.read(data)) != -1) {
                os.write(data);
                os.flush();
            }
    
            // 关闭的时候,先打开的后关闭
            os.close();
            is.close();
        }
    }
    

    2. 转换流

    转换流是Java中的处理流,主要的作用是在字节流和字符流之间的转换,在使用的时候要注意到字符集的选择,否则会出现乱码的情况。这里提一下编码和解码: 字符到字节的过程称为编码,字节到字符的过程称为解码。

    实例如下:

    字符流转换为字节流(编码过程)
    import java.io.*;
    
    /**
     * 使用转换流实现字节到字符的转换,写出到外部文件
     * 字符流 ----> 字节流
     */
    public class Demo04 {
    
        public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException ,IOException{
            File file01 = new File("src/testStream/1.txt");
    
            // 使用指定的字符集,将字符流转成字节流
            OutputStream os = new FileOutputStream(file01);
            Writer fileWriter = new OutputStreamWriter(os, "GBK");
    
            String content = new String("冯振振");
    
            fileWriter.write(content);
    
            fileWriter.flush();
    
            fileWriter.close();
        }
    }
    
    字节流转换为字符流(解码过程)
    import java.io.*;
    
    /**
     * 使用转换流实现字节到字符的转换,读取外部文件
     * 字节流 ----> 字符流
     */
    public class Demo03 {
    
        public static void main(String[] args) {
            File file01 = new File("src/testStream/1.txt");
    
            try {
                // 使用字节流读取文本,然后使用指定的字符集,将字节流转成字符流
                // 如此一来,就不会出现读取文本乱码的问题
                InputStream tempStream = new FileInputStream(file01);
                Reader is = new InputStreamReader(tempStream, "Unicode");
    
                char[] flush = new char[1024];
                int len;
                while ((len = is.read(flush)) != -1) {
                    System.out.println(flush);
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                System.out.println("文件未找到");
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("文件读取失败");
            }
        }
    }
    

    3. 字节数组流

    字节数组流也是用来处理数据的一种形式,在使用的时候与前面提到的几种流相似,也有输入流(ByteArrayInputStream)和输出流(ByteArrayOutputStream)。下面给出连个方法的实例,介绍一下字节数组流的使用方式:

    将字节数组流的数据写入到外部文件中
    /**
     * 将字节数组写入到外部文件中
     * @param src 字节数组
     * @param destPath 写出的外部文件
     * @throws IOException
     */
    public static void write(byte[] src, String destPath) throws IOException {
    
        // 根据传入的参数,创建字节数组输入流和文件输出流
        File dest = new File(destPath);
        InputStream is = new BufferedInputStream(new ByteArrayInputStream(src));
        OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));
    
        byte[] flush = new byte[10];
        int len = 0;
    
        // 不断读取字节数组输入流,写出到外部文件
        while (-1 != (len = is.read(flush))) {
            os.write(flush, 0, len);
        }
    
        os.flush();
    
        os.close();
        is.close();
    }
    
    以字节数组流的形式读取外部文件中的内容
    /**
     * 从外部文件中读取字节数组内容
     * @param srcPath 外部文件的路径
     * @return 包含外部文件的字节数组
     * @throws IOException
     */
    public static byte[] read(String srcPath) throws IOException {
        File src = new File(srcPath);
        InputStream is = new BufferedInputStream(new FileInputStream(src));
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
    
        byte[] flush = new byte[10];
        int len = 0;
    
        while (-1 != (len = is.read(flush))) {
            bos.write(flush, 0, len);
        }
        bos.flush();
    
        return bos.toByteArray();
    }
    

    4. 数据流

    数据流可以实现Java中数据类型的写入与写出,不仅保存数据值本身,还可以保存数据的类型。

    其中数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。

    需要注意的是,使用数据输出流将数据类型写出到外部文件中的时候,内容和字节码文件相似,是一些机器识别的编码,我们看不懂。在读取外部文件中数据流内容的时候,读取的顺序要和写入的顺序相同,否则会发生错误。下面给出两个实例:

    将Java中的数据流写出到外部文件
    public static void write() throws FileNotFoundException, IOException {
        File dest = new File("src/testStream/3.txt");
        DataOutputStream dos = new DataOutputStream(
                new BufferedOutputStream(new FileOutputStream(dest))
        );
    
        int num = 6;
        double doubleNum = 20.5;
        String name = "fengzhen";
    
        dos.writeInt(num);
        dos.writeDouble(doubleNum);
        dos.writeUTF(name);
    
        dos.close();
    }
    
    从外部文件中读取Java数据流
    public static void read(String srcPath) throws FileNotFoundException, IOException {
        File srcFile = new File(srcPath);
        DataInputStream dis = new DataInputStream(
                new BufferedInputStream(new FileInputStream(srcFile))
        );
    
       int num =  dis.readInt();
       double doubleNum = dis.readDouble();
       String name = dis.readUTF();
    
       System.out.println(num);
       System.out.println(doubleNum);
       System.out.println(name);
    
    }
    

    5. 对象流

    对象流和上面的数据流一样,可以实现对象的写入与写出。对象的写入与写出又被称为 反序列化序列化

    但是并不是每一个对象都可以被写入写出,也不是每一个属性能够被写入和写出。首先我们先定义一个Student类,注意看其中的注释:

    /**
     * 定义一个Student类,该类必须继承Serializable接口,才能实现对象的写入与写出
     * 该接口是一个空接口,里面没有定义方法
     */
    public class Student implements java.io.Serializable {
    
        private String name;
        private double height;
        private transient String gender;        // 不需要序列化的属性,使用transient修饰
    
        public Student() {
        }
    
        public Student(String name, double height, String gender) {
            this.name = name;
            this.height = height;
            this.gender = gender;
        }
    
        public String getName() {
            return name;
        }
    
        public double getHeight() {
            return height;
        }
    
        public String getGender() {
            return gender;
        }
    }
    

    下面提供两个方法的实例,了解一下对象流的使用:

    将Java程序中的对象写出到外部文件
    /**
     * 将对象写出到外部文件中,即对象的序列化
     * @throws IOException
     */
    public static void write() throws IOException {
        File dest = new File("src/testStream/3.txt");
        ObjectOutputStream dos = new ObjectOutputStream(
                new BufferedOutputStream(new FileOutputStream(dest))
        );
    
        Student stu = new Student("Tom", 175, "male");
    
        dos.writeObject(stu);
    
        dos.close();
    }
    
    从外部文件中读取对象
    /**
     * 从外部文件中读取对象,即对象的反序列化
     * @param srcPath
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static void read(String srcPath) throws IOException, ClassNotFoundException {
        File srcFile = new File(srcPath);
        ObjectInputStream dis = new ObjectInputStream(
                new BufferedInputStream(new FileInputStream(srcFile))
        );
    
        Student stu = (Student) dis.readObject();
    
        System.out.println(stu.getGender());        // 没有被序列化,结果为null
        System.out.println(stu.getHeight());
        System.out.println(stu.getName());
    }
    

    相关文章

      网友评论

          本文标题:Java学习——day 17

          本文链接:https://www.haomeiwen.com/subject/ybutdqtx.html