Java IO知识体系详解
Posted 傲骄鹿先生
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java IO知识体系详解相关的知识,希望对你有一定的参考价值。
我是傲骄鹿先生,沉淀、学习、分享、成长。
如果你觉得文章内容还可以的话,希望不吝您的「一键三连」,文章里面有不足的地方希望各位在评论区补充疑惑、见解以及面试中遇到的奇葩问法
目录
4、序列化 & Serializable & transient
一、Java IO框架之知识体系
创建一个好的I/O系统不是一件容易的事,难度似乎来自于需要覆盖所有的可能性。因为不仅存在各种I/O源端(文件、控制台、网络连接等),还需要以多种不同的方式与这些I/O源端(顺序、随机、缓冲、二进制、按字符、按行、按字)进行通信。Java类库的设计者通过创建大量的类来解决这个问题。
最全源码详细解读io流: Java8 I/O源码-目录_潘威威的博客-CSDN博客
二、Java IO分类(传输,操作)
1、IO理解分类-从传输方式上
从数据传输方式或者说是运输方式角度看,可以将 IO 类分为:字节流和字符流
字节流(整体结构如下,部分派生类有缺失)
字符流(整体结构如下,部分派生类有缺失)
字节流和字符流的区别
- 字节流读取单个字节,字符流读取单个字符(一个字符根据编码的不同,对应的字节也不同,如 UTF-8 编码中文汉字是 3 个字节,GBK编码中文汉字是 2 个字节。)
- 字节流用来处理二进制文件(图片、MP3、视频文件),字符流用来处理文本文件(可以看做是特殊的二进制文件,使用了某种编码,人可以阅读)。
字节转字符 Input/OutputStreamReader/Writer
编码就是把字符转换为字节,而解码是把字节重新组合成字符。如果编码和解码过程使用不同的编码方式那么就出现了乱码。- GBK 编码中,中文字符占 2 个字节,英文字符占 1 个字节;
- UTF-8 编码中,中文字符占 3 个字节,英文字符占 1 个字节;
- UTF-16be 编码中,中文字符和英文字符都占 2 个字节。
2、IO理解分类 - 从数据操作上
从数据来源或者说是操作对象角度看,IO 类可以分为:
文件(file):FileInputStream、FileOutputStream、FileReader、FileWriter
数组([]):
-
字节数组(byte[]): ByteArrayInputStream、ByteArrayOutputStream
-
字符数组(char[]): CharArrayReader、CharArrayWriter
管道操作:PipedInputStream、PipedOutputStream、PipedReader、PipedWriter
基本数据类型:DataInputStream、DataOutputStream
缓冲操作:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter
打印:PrintStream、PrintWriter
对象序列化反序列化:ObjectInputStream、ObjectOutputStream
转换:InputStreamReader、OutputStreamWriter
三、Java IO-常见类的使用
-
磁盘操作: File
-
字节操作: InputStream 和 OutputStream
-
字符操作: Reader 和 Writer
-
对象操作: Serializable
-
网络操作: Socket
1、File相关
File 类可以用于表示文件和目录的信息,但是它不表示文件的内容。递归地列出一个目录下所有文件:
public static void listAllFiles(File dir)
if (dir == null || !dir.exists())
return;
if (dir.isFile())
System.out.println(dir.getName());
return;
for (File file : dir.listFiles())
listAllFiles(file);
2、字节流相关
public static void copyFile(String src, String dist) throws IOException
FileInputStream in = new FileInputStream(src);
FileOutputStream out = new FileOutputStream(dist);
byte[] buffer = new byte[20 * 1024];
// read() 最多读取 buffer.length 个字节
// 返回的是实际读取的个数
// 返回 -1 的时候表示读到 eof,即文件尾
while (in.read(buffer, 0, buffer.length) != -1)
out.write(buffer);
in.close();
out.close();
3、实现逐行输出文本文件的内容
public static void readFileContent(String filePath) throws IOException
FileReader fileReader = new FileReader(filePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line;
while ((line = bufferedReader.readLine()) != null)
System.out.println(line);
// 装饰者模式使得 BufferedReader 组合了一个 Reader 对象
// 在调用 BufferedReader 的 close() 方法时会去调用 Reader 的 close() 方法
// 因此只要一个 close() 调用即可
bufferedReader.close();
4、序列化 & Serializable & transient
序列化就是将一个对象转换成字节序列,方便存储和传输。- 序列化: ObjectOutputStream.writeObject()
- 反序列化: ObjectInputStream.readObject()
public static void main(String[] args) throws IOException, ClassNotFoundException
A a1 = new A(123, "abc");
String objectFile = "file/a1";
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(objectFile));
objectOutputStream.writeObject(a1);
objectOutputStream.close();
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(objectFile));
A a2 = (A) objectInputStream.readObject();
objectInputStream.close();
System.out.println(a2);
private static class A implements Serializable
private int x;
private String y;
A(int x, String y)
this.x = x;
this.y = y;
@Override
public String toString()
return "x = " + x + " " + "y = " + y;
transient
transient 关键字可以使一些属性不会被序列化。
ArrayList 中存储数据的数组 elementData 是用 transient 修饰的,因为这个数组是动态扩展的,并不是所有的空间都被使用,因此就不需要所有的内容都被序列化。通过重写序列化和反序列化方法,使得可以只序列化数组中有内容的那部分数据。
private transient Object[] elementData;
5、Java 中的网络支持:
- InetAddress: 用于表示网络上的硬件资源,即 IP 地址;
- URL: 统一资源定位符;
- Sockets: 使用 TCP 协议实现网络通信;
- Datagram: 使用 UDP 协议实现网络通信。
InetAddress
没有公有的构造函数,只能通过静态方法来创建实例。InetAddress.getByName(String host);
InetAddress.getByAddress(byte[] address);
6、URL
可以直接从 URL 中读取字节流数据。public static void main(String[] args) throws IOException
URL url = new URL("http://www.baidu.com");
/* 字节流 */
InputStream is = url.openStream();
/* 字符流 */
InputStreamReader isr = new InputStreamReader(is, "utf-8");
/* 提供缓存功能 */
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null)
System.out.println(line);
br.close();
7、Sockets
- ServerSocket: 服务器端类
- Socket: 客户端类
- 服务器和客户端通过 InputStream 和 OutputStream 进行输入输出。
8、Datagram
- DatagramSocket: 通信类
-
DatagramPacket: 数据包类
系列文章持续更新,微信搜一搜「傲骄鹿先生 」,回复【面试】有准备的一线大厂面试资料。
以上是关于Java IO知识体系详解的主要内容,如果未能解决你的问题,请参考以下文章