写点什么

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

发布于: 2021 年 04 月 23 日

摘要: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(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 接口则需要

参考资料

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


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

发布于: 2021 年 04 月 23 日阅读数: 34
用户头像

提供全面深入的云计算技术干货 2020.07.14 加入

华为云开发者社区,提供全面深入的云计算前景分析、丰富的技术干货、程序样例,分享华为云前沿资讯动态,方便开发者快速成长与发展,欢迎提问、互动,多方位了解云计算! 传送门:https://bbs.huaweicloud.com/

评论

发布
暂无评论
总是记不住java的IO流用法?用N个问题教你掌握java IO流