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

举报
breakDawn 发表于 2021/04/20 20:33:05 2021/04/20
【摘要】 文件APIQ: File类可以用来做目录操作吗?A:可以。File对象本身可以是目录。调用file.mkdirs()即可创建目录。Q:直接调用file.delete()可以删除目录吗?A:如果是文件或者空目录,可以直接删除。但如果目录中有文件或者子目录,则必须递归删除。 private static boolean deleteDir(File dir) { if (d...

文件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()) {...}
  1. File类的静态exist方法, File.exist(Path path)
Path filePath = Paths.get(testFilePath);
if (Files.exists(filePath) {...}

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

字节输入流InputStream

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

  • 字节数组char[] 作为输入源的InputStream类是————ByteArrayInputStream
  • 用文件作为输入源的InputStream类是?————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:
是否支持在文件末追加的意思。
image.png

默认是false,指的是覆盖整个文本。
如果设置成true,会在要写入的文件后面追加本次写入的内容。


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

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

A:

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

  • close关闭此输出流并释放与此相关联的任何系统资源, 会调用flush,除了flushBuffer,还会调用父类的flush。

  • 不会丢数据,因为上面这条原因。

  • 多次调用不会报错。

    image.png

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(System.in));
  • 用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接口则需要

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。