Java IO类结构
FileSystem
JDK 里面抽象出了一个 FileSystem 类
来表示文件系统,不同的操作系统通过继承该类实现各自的文件系统,比如 Windows 操作系统则为 WinNTFileSystem
,而 Unix 操作系统为 UnixFileSystem
. 它们的继承关系如下:
笔者当前处于Windows
系统, 所以这里只存在WinNTFileSystem
类. 如果当前是Linux
系统, 那么就会只存在UnixFileSystem
.
WinNTFileSystem 类
我们可以看一下该类的定义:
这里我们可以看到, WinNTFileSystem
提供了很多IO操作方法, 其中定义的三个成员属性slash, altSlash, semicolon
都在构造方法中所定义了, 并且该类是不允许除 java.io
以外的包进行实例化的, 因为该类的访问修饰符为默认.
该类定义的很多方法都是由native
关键字所定义的, 最终会调用动态链接库中C实现的Java Native
方法.
File 类
File
类放置在java.io
包下, 相信我们最初学习Java IO流
时已经对 File类有所了解了. 我们可以直接在我们自己写的程序中new File
也是因为File
类的修饰符为public
, 并且该类会对WinNTFileSystem
类存在一个依赖关系, 如图:
当然, 有依赖关系, File 类中很多方法也会对fs
成员属性进行调用, 如图:
可以看到, File
类的很多方法也只是对WinNTFileSystem
类进行一个包装调用, 归根结底也会调用到我们的native
方法中.
FileInputStream && FileOutputStream 类
当然也不是所有文件操作都是调用的WinNTFileSystem
类中的方法, FileInputStream 的调用过程如下:
FileOutputStream 的调用如下:
FileSystemProvider 类
上面一系列都在介绍JAVA-BIO
的文件流, 当然除了BIO (java.io)
还有NIO (java.nio)
. 而java.nio
的实现是sun.nio
, 下面笔者将给出案例:
当然了, 这个类的使用也依赖于FileSystemProvider
, 如图:
而FileChannel::transferTo
是将通道1
的数据给予通道2
, 该方法也同样是使用native
关键字定义的, 如图:
NIO的文件操作在不同的系统的最终实现类也是不一样的,比如Mac的实现类是: sun.nio.fs.UnixNativeDispatcher
,而Windows的实现类是sun.nio.fs.WindowsNativeDispatcher
。
API 调用文件读取 && 写入
IO
public class FileTester {
public static void main(String[] args) throws Exception { // 文件读取
FileInputStream fis = new FileInputStream("C:/Windows/win.ini");
int len;
byte[] myChunk = new byte[1024];
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
while ((len = fis.read(myChunk)) > 0) {
byteArrayOutputStream.write(myChunk, 0, len);
}
System.out.println(byteArrayOutputStream.toString());
}
}
public class FileTester {
public static void main(String[] args) throws Exception { // 文件写入
FileOutputStream fileOutputStream = new FileOutputStream("D:/1.txt");
fileOutputStream.write("Hi Heihu".getBytes());
fileOutputStream.flush();
}
}
NIO
public class FileTester {
public static void main(String[] args) throws Exception {
Path p1 = Paths.get("C:/Windows/win.ini");
byte[] bytes = Files.readAllBytes(p1);
System.out.println(new String(bytes)); // 读取文件内容
Path p2 = Paths.get("D:/1.txt");
Files.write(p2, "hi heihu577".getBytes()); // 写入文件内容
}
}
当然还可以通过 buffer 与 channel:
public class FileTester {
public static void main(String[] args) throws Exception { // 读取文件
FileInputStream fileInputStream = new FileInputStream("C:/Windows/win.ini");
FileChannel channel = fileInputStream.getChannel();
ByteBuffer allocate = ByteBuffer.allocate(1024);
channel.read(allocate);
allocate.flip();
System.out.println(new String(allocate.array()));
}
}
public class FileTester {
public static void main(String[] args) throws Exception { // 写入文件
FileOutputStream fileOutputStream = new FileOutputStream("D:/1.txt");
FileChannel channel = fileOutputStream.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
byteBuffer.put("Hi~ Heihu577".getBytes());
byteBuffer.flip();
channel.write(byteBuffer);
}
}
Reference
Windows IO 上: https://juejin.cn/post/6844903510882942984
Windows IO 中: https://juejin.cn/post/6844903512413831182
Windows IO 下: https://juejin.cn/post/6844903517816094728
Unix IO 上: https://juejin.cn/post/6844903520047644680
Unix IO 中: https://juejin.cn/post/6844903520458522632
Unix IO 下: https://juejin.cn/post/6844903520500449287
原文始发于微信公众号(Heihu Share):语言特性 | JAVA IO类结构
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论