• 总是记不住java的IO流用法?用N个问题教你掌握java IO流


    摘要:Java IO 体系看起来类很多,感觉很复杂,但其实是 IO 涉及的因素太多了。在设计 IO 相关的类时,编写者也不是从同一个方面考虑的,所以会给人一种很乱的感觉,并且还有设计模式的使用,更加难以使用这些 IO 类,所以特地对 Java 的 IO 做一个总结。

    本文分享自华为云社区《总是记不住java的IO流用法?用N个问题教你掌握java IO流》,原文作者:breakDraw 。

    Java IO 体系看起来类很多,感觉很复杂,但其实是 IO 涉及的因素太多了。在设计 IO 相关的类时,编写者也不是从同一个方面考虑的,所以会给人一种很乱的感觉,并且还有设计模式的使用,更加难以使用这些 IO 类,所以特地对 Java 的 IO 做一个总结。

    文件API

    Q: File类可以用来做目录操作吗?

    A:可以。

    File对象本身可以是目录。调用file.mkdirs()即可创建目录。

    Q:直接调用file.delete()可以删除目录吗?

    A:如果是文件或者空目录,可以直接删除。

    但如果目录中有文件或者子目录,则必须递归删除。

      private static boolean deleteDir(File dir) {
            if (dir.isDirectory()) {
                String[] children = dir.list();
           //递归删除目录中的子目录下
                for (int i=0; i<children.length; i++) {
                    boolean success = deleteDir(new File(dir, children[i]));
                    if (!success) {
                        return false;
                    }
                }
            }
            // 目录此时为空,可以删除
            return dir.delete();
        }

    Q: 有哪些方法判断给定路径下文件是否存在?

    A:

    1.File类的exists方法: file.exist(string)

    File testFile = new File(testFilePath);
    if(!testFile .exists()) {...}

    2.File类的静态exist方法, File.exist(Path path)

    Path filePath = Paths.get(testFilePath);
    if (Files.exists(filePath) {...}

    注意静态方法和非静态方法的区别

    字节输入流InputStream

    说一下以下这些特点对应哪些Input Stream类

    • 字节数组char[] 作为输入源的Input Stream类是——ByteArrayInputStream
    • 用文件作为输入源的Input Stream类是?——FileInputStream
    • 用字符串作为输入源的是?——StringBufferInputStream
    • 用于多线程之间管道通信的输入源是——PipeInputStream

    Q: FilterInputStream是什么?

    A: 用于装饰上面这些输入流的,可以叠加,每装饰一层就相当于增加了1个功能。

    InputStream inputStream = new FilterInputStream(InputStream)

    以下这些特点分别对应哪些FilterInputStream?

    • 装饰后,不仅可读字符串,还可读取例如int、long等java基本类型的是————DataInputStream
      DataInputStream里面会支持readInt、readLong等方法。
    • 装饰后,支持分批缓冲读取读取的是————BufferedInputStream
      创建BufferedInputStream时,我们会通过它的构造函数指定某个输入流为参数。BufferedInputStream会将该输入流数据分批读取,每次读取一部分到缓冲中;操作完缓冲中的这部分数据之后,再从输入流中读取下一部分的数据。
    • 其他:
      PushbackInputStream: 具有1个能回退上一个字节的缓冲区
      ObjectInputStream : 一般用于反序列化读入
      LineNumberInputStream: 可跟踪输入流中的行号

    字节输出流OutputStream

    OutputStream包含
    ByteArrayOutputStream 输出到缓冲区
    FileOutputStream 写到文件
    PipedOutputStream 写入管道
    FilterOutputStream

    而FilterOutputStream 包含

    • DataOutputStream (可以out.writexxx各种类型的数据,writeDouble, writeUTF, reader也一样,可以读想要的数据类型)、
    • PringtStream (输出到文件用这个, 该类.println(str)即可写入文件)
    • BufferOutputString

    FileOutputStream相关
    Q:new FileOutputStream(name, true),这个构造里的true参数是做什么用的?

    A:是否支持在文件末追加的意思。

    默认是false,指的是覆盖整个文本。

    如果设置成true,会在要写入的文件后面追加本次写入的内容。

    Q:

    BufferOutputStream相关概念(其实是考缓冲区是否需要刷新之类的问题)

    • BufferOutputStream里的flush()方法是做什么的?
    • BufferOutputStream调用close后,会触发flush()来刷新缓冲区吗?
    • BufferOutputStream调用close可能会丢数据吗?
    • BufferOutputStream多次调用close会报错吗?

    A:

    • flush把缓冲区里的数据写入文件,并刷新缓冲区

    • close关闭此输出流并释放与此相关联的任何系统资源, 会调用flush,除了flushBuffer,还会调用父类的flush。
    • 不会丢数据,因为上面这条原因。
    • 多次调用不会报错。

    Reader和Writer

    Q: Reader/Writer和InputStream/OutputStream的区别?
    A:

    • InputStream是表示 字节输入流 的所有类的超类
      Reader是用于读取 字符流 的抽象类
      InputStream提供的是字节流的读取,而非文本读取,这是和Reader类的根本区别。
      即用Reader读取出来的是char数组或者String ,使用InputStream读取出来的是byte数组。
    • Reader/Writer提供兼容Unicode、面向字符的IO功能,为了国际化
    • 用reader读取标准输入:
      BufferedReader bufr = new BufferedReader(new InputStreamReader());
    • 用Writer进行标准输出:
      BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));

    设置编码:

    InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");  
    BufferedReader read = new BufferedReader(isr);  

    序列化问题

    Q: 对某对象进行序列化时, 如何让里面某个敏感成员不被序列化?
    A:

    • 方法一:可使用transient关键字处理那个敏感成员
    • 方法二:可以通过覆盖Serializable接口的writeObject和readObject来实现序列化, 但是方法签名必须是private void writeObject(ObjetOutputStream stream) throw IOException;
    • 方法三: 实现Externalizable接口,可自定义实现writeExternal以及readExternal方法

    Q: Externalizable和Serializable哪个快?
    A: Externalizable更快。

    Q: Externalizable需要产生序列化ID吗?

    A: 采用Externalizable无需产生序列化ID(serialVersionUID)~而Serializable接口则需要

    参考资料

    https://blog.csdn.net/qq_26222859/article/details/50994113
    https://blog.csdn.net/weixin_44117272/article/details/90767074

     

    点击关注,第一时间了解华为云新鲜技术~

  • 相关阅读:
    HTML基础学习笔记
    CSS-精灵图片的使用(从一张图片中截图指定位置图标)
    侧边栏显示
    HTML <form> action 属性
    2018年寒假小记
    算法提高--接水问题
    基础练习--huffman
    ...
    基础算法
    枚举--最长单词--蓝桥杯
  • 原文地址:https://www.cnblogs.com/huaweiyun/p/14693835.html
Copyright © 2020-2023  润新知