FileDescriptor
FileDescriptor,顾名思义:“文件描述符”,用来表示开放文件、开放套接字。这个概念来自于*nux
文件系统,Linux继承Unix “一切皆文件” 的概念:
文件类型 | 标记符 |
---|---|
普通文件 | - |
目录文件(directory) | d |
字符设备文件(character) | c |
块设备文件(block) | b |
套接字文件(socket) | s |
管道文件(pipe) | p |
链接文件(link) | l |
POSIX标准中打开文件的函数如下:
// 这里返回的int值就是FileDescriptor
int open(const char *path, int oflag, .../*,mode_t mode */);
这里返回的int值就是FileDescriptor,它被用来标识一个文件,你可以把它理解为一个“文件句柄”。
但是只有FileDescriptor,我们是无法读写文件的,我们还需要FileInputStream、FileOutputStream或RandomAccessFile等类来实现文件的读写。这几个类的使用下面会依次讲到。
而操作系统中有三个标准的I/O流:
FileDescriptor | 名称 | POSIX常量标识(unistd.h) | 标准IO常量标识(stdio.h) |
---|---|---|---|
0 | 标准输入流 | STDIN_FILENO | stdin |
1 | 标准输出流 | STDOUT_FILENO | stdout |
2 | 标准错误流 | STDERR_FILENO | stderr |
FileDescriptor类中也定义了这三个常量:
public static final FileDescriptor in = standardStream(0);
public static final FileDescriptor out = standardStream(1);
public static final FileDescriptor err = standardStream(2);
但是通常我们都是通过System中的三个常量来使用标准I/O流,因为它已经帮我们封装好了:
public final static InputStream in = null;
public final static PrintStream out = null;
public final static PrintStream err = null;
public static void setIn(InputStream in) {
checkIO();
setIn0(in);
}
public static void setOut(PrintStream out) {
checkIO();
setOut0(out);
}
public static void setErr(PrintStream err) {
checkIO();
setErr0(err);
}
private static native void setIn0(InputStream in);
private static native void setOut0(PrintStream out);
private static native void setErr0(PrintStream err);
private static void initializeSystemClass() {
...
FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
setIn0(new BufferedInputStream(fdIn));
setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
...
}
有关标准I/O的内容可以参考《JavaIO总结与巩固》
File
FileDescriptor为文件的读写功能提供了基础,而File则是提供文件的增删查功能。
在Java中File更像是一个文件路径,只是Java在File类中还提供了文件的增删查的操作。所以File类是个“大杂烩”,功能相当的丰富。也许正是因为File类功能太多,在Java1.7的NIO2中把它的功能划分成了Path
和Files
两个类。
有关NIO的内容会在后续的文章中讲到
File的功能大部分是由FileSystem类来实现的,而FileSystem的实现类根据平台分为两种:WinNTFileSystem
代表微软的Windows系列的操作系统,UnixFileSystem
代表了BSD,Linux,MaxOS为首遵循POSIX规范的类Unix系统,但FileSystem及其实现类我们无法直接使用它(因为是package访问级别)。
注意这里的FileSystem不是
java.nio.file
包中的FileSystem。
File类有四个公有的构造方法: