Java IO流技术

Posted dbc0801

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java IO流技术相关的知识,希望对你有一定的参考价值。

Java IO流技术

技术图片

Java IO基本总结

  Java的IO技术就是用来处理数据的。比如从文件中读取数据,或者将数据写到文件中。在网络中传输的都是二进制,即字节码,我们需要在传输之前,将我们程序中的数据转换成字节码才能进行传输。Java的IO包内就提供了完成这些工作的工具类。

  总的来说:当需要以二进制的形式来处理文件时,即不涉及文本内容的操作时,我们可以选择InputStream和OutputStream来完成我们的工作。当需要完成处理字符串相关的工作时,就需要使用Reader和Writer来完成工作。当需要向文件或其它源写入或传输时,应该使用OutputStream和Writer,当需要从文件或其它源读取内容时,应该使用Reader和InputStream。

  另外,BufferedReader和BufferedWriter,以及BufferedInputStream和BufferedOutputStream是利用了缓冲技术的IO操作,主要是可以提高文件读写的效率。

Java IO基本使用

以二进制读取文件

  

    public static void test04(String filePath) {
        // 二进制形式读取文件内容
        File f = new File(filePath);
        InputStream is = null;
        try {
            is = new FileInputStream(f);
            // 使用缓冲
            BufferedInputStream bis = new BufferedInputStream(is);
            byte[] buffer = new byte[1024]; // 每次读1024
            int len = -1;
            while ((len = bis.read(buffer)) != -1) {
                /**
                 * 每次读取到的内容被保存到 buffer 字节数组 len返回读取到的字节的长度,当返回-1时表示:文件已经读取完毕
                 */
                System.out.println(Arrays.toString(buffer));
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(is!=null) {
                try {
                    // 释放资源
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

 

 

 

 

二进制读取并保存

  通过这种方法,可以实现一个简单的文件复制。

    public static void test05(String src, String desc) {
        File f1 = new File(src);
        File f2 = new File(desc);

        byte[] buffer = new byte[1024];
        int len = -1;
        /**
         * 使用 try-with-resource 将需要读写的文件放到 try 中进行声明,就不需要手动释放资源
         * try 中声明的对象只能是 需要进行读写的对象,其它的不能放到这里进行声明
         */
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f1));
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f2));

        ) {
            while ((len = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
                bos.flush();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

 

 

处理文本文件

  在处理文本文件时,应该清楚的了解自己应该使用什么字符集来处理文件。使用错误的字符集会导致乱码。

    public static void test06(String filePath) {
        File f = new File(filePath);
        try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f), "utf-8"));) {
            /**
             * 在 InputStreamReader实例化时,传入指定字符集 InputStreamReader是一个包装类,通过它,可以将字节转化为字符
             * 很明显,它需要一个 InputStream 的子类。
             */
            String line = null;
            while((line=br.readLine())!=null) {
                System.out.println(line);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }

 

 

将Java中的数据类型序列化

  当需要对Java中的基本数据类型进行序列化时,就需要使用DateOutputStream和DataInputStream来进行操作了。

  这次,我们把Java中的一些基本数据类型保存在 ByteArrayOutputStream中 进行保存,并 通过 ByteArrayInputStream 来读取。

    public static void test07(Object... objects) {
        // 实现不定量参数的传递
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(baos); // 向ByteArrayOutputStream中写入数据
        try {
            dos.writeLong((Long)objects[0]);
            /**
             *  将 ByteArrayOutputStream 中的内容 放到 ByteArrayInputStream 中进行读取
             *  ByteArrayInputStream 需要一个 字节数组
             */
            
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            
            // 需要一个 DataInputStream 来 反序列化
            DataInputStream dis = new DataInputStream(bais);
            /**
             * 开始读操作,应该按照一一对应的原则来进行读取
             */
            Long l = (Long)dis.readLong();
            System.out.println(l);
        } catch (IOException e) {
            e.printStackTrace();
        }        
    }

 

将自定义的对象序列化和反序列化

  这次将Java中自定义的对象 进行实例化,并保存到文件中,然后读取。要想实现自定义对象的序列化,必须实现 Serializable接口。

  需要用到 ObjectOutputStream和ObjectInputStream。

// 类的定义
class School implements Serializable {
    private static final long serialVersionUID = 7278116284818149932L;
    private String name;
    private String area;
    private transient String secret; // 不会被序列化的字段

    public String toString() {
        return this.name + "<" + this.area + ">";
    }

    public School(String name, String area, String secret) {
        super();
        this.name = name;
        this.area = area;
        this.secret = secret;
    }

    public School() {
        // 空构造器
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getArea() {
        return area;
    }

    public void setArea(String area) {
        this.area = area;
    }

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }

}

// 类的实例化 及 保存和 读取

    public static void test08(String filePath) {
        /**
         * 将实例化对象写入到 filePath指定的文件中 读取 desc中的内容,并打印到终端
         */
        School s1 = new School("燕山大学", "秦皇岛", "不会被序列化的字符串");
        School s2 = new School("蠡县中学", "保定", "这是一个秘密信息");
        File f = new File(filePath);
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));) {
            /**
             * 实例化对象序列化
             */
            oos.writeObject(s1);
            oos.writeObject(s2);
            oos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        /**
         * 从文件中读取二进制文件,并反序列化
         */
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));) {
            School s3 = (School)ois.readObject();
            School s4 = (School)ois.readObject();
            System.out.println(s3);
            System.out.println(s4);
            /**
             * 尝试获取未通过序列化的属性
             * 未序列化的属性为null或0
             */
            System.out.println("现获取未序列化的属性"); 
            System.out.println(s3.getSecret());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

 

说明

  本博客所有的文章都会随着本人的不断积累,而不断的更新。转载请注明出处。

 

 

  

以上是关于Java IO流技术的主要内容,如果未能解决你的问题,请参考以下文章

关于java中io流的关闭问题,部分代码,这种情况用不用关闭new FileReader(file)?

JAVA IO流相关代码(Properties类的常见方法与应用)

JAVA IO流相关代码(Properties类的常见方法与应用)

java中IO流读完一次以后是否,Io流就会被清空了。我再想怎么还能读到数据呢?

Java IO流技术

Java技术专题「Java8技术盲区」让我们来看看新一代IO流的开发指引(流升级功能体系)