JavaIO中的文件处理——File和RandomAccessFile

上面几篇文章整理了JavaIO的字节流和字符流处理相关的类,而这些字节流和字节流的来源和目的也是IO中需要考虑的要点。而在处理IO中,最普遍最常见的莫过于磁盘中的文件。我们这篇就整理下JDK中和文件相关的Java类。

其实在前面的文章中,我们已经介绍或者提到了一些和文件间接相关的类,如FileInputStream、FileOutputStream、FileReader、FileWriter、FileDescriptor。除此之外,在java.io包中,还有和文件相关的两个独立的类,就是File和RandomAccessFile。

0. File

即java.io.File。这个类名很直接,就是“文件”的意思。但遗憾的是,对文件内部数据的访问不能用这个类直接做到。在《Thinking in Java》第四版中,作者这样描述过:

The File class has a deceiving name; you might think it refers to a file, but it doesn’t. In fact, “FilePath” would have been a better name for the class. It can represent either the name of a particular file or the names of a set of files in a directory.

实际上,按本人的理解,File这个类主要是针对文件系统中目录相关操作而做的,是对文件系统中文件或目录属性的一个封装

下面我们来简要看下这个类。

public class File implements Serializable, Comparable

可见首先File类是可序列化的,同时又是可比较的。通常这个比较是按字母顺序排列,这个决定于操作系统或者说文件系统。

在JDK1.7中,这个类的方法实在是太多了,这里就不一一列举。这些方法可以分为几大类:

  • 构造方法。
  • 文件路径相关操作。大部分是字符串处理操作,还有到URL/URI类的转换。
  • 文件属性相关操作方法。如可读、可写、可执行属性,判断是目录还是文件的属性,文件大小,修改时间,是否为隐藏文件等。这些通常对应于Linux中端下ls命令所得到的属性。
  • 针对文件系统本身的操作。如删除,创建目录,显示文件列表等,对应于Linux命令rm、mkdir、ls等。稍微提下,获取文件列表有很多重载方法,其中有两个方法使用到了FileFilter和FilenameFilter接口。
  • 序列化方法。
  • 新版本JDK包增加的对NIO支持的方法。

而上述所列的方法,实际上是对操作系统中的底层文件系统的封装。在SunJDK中,这些方法通常都包装了对fs对象属性方法的调用。这个fs是一个java.io包中的非public的抽象类FileSystem,包级别可见。所以,这个java.io.FileSystem类也就没有在JavaSE 的API文档中。

这个FileSystem是抽象类,其中的方法大部分是abstract的,还有native的。它的实现子类随不同操作系统的JDK而不同。如在Windows操作系统平台上的JDK中就包含子类java.io.Win32FileSystem和java.io.WinNTFileSystem等。这样,文件操作的方法最终就经由JDK调用操作系统的底层方法。

除了fs属性外,File中还包含路径和分隔符相关的各种属性,但他们都围绕fs,即文件系统对象来实现。

1. FileFilter & FilenameFilter

在File中有获取文件列表的很多重载方法,其中有这样3个方法:

  • public String[] list(FilenameFilter filter)
  • public File[] listFiles(FilenameFilter filter)
  • public File[] listFiles(FileFilter filter)

关于FileFilter和FilenameFilter,我想大家看到这里也应该猜到他们的用处和大概实现了。

这两个接口源码如下,用来指定获取文件列表的过滤规则。

public interface FilenameFilter {
   boolean accept(File dir, String name);
}

 

public interface FileFilter {
    boolean accept(File pathname);
}

方便了各类文件列表需求的自定义实现。

2. RandomAccessFile

上面讲File的时候,提到通过File并不能直接访问文件数据,只能进行文件系统中相关的操作。java.io.RandomAccessFile弥补了这点,它才是能够访问文件数据的类。

对于文件的数据访问,我们在前面的文章中也整理过FileInputStream、FileOutputStream、FileReader和FileWriter。

其实,RandomAccessFile好比把输入流和输出流综合了起来,针对文件进行读写。其中也有FileInputStream和FileOutputStream中的FileDescriptor类对象属性fd。

再来看看类的声明:

public class RandomAccessFile implements DataOutput, DataInput, Closeable

RandomAccessFile 实现了DataOutput和DataOutput接口。这两个接口方便数据到各类基本类型的数据读取转换。详细可见前面的文章:

java.io包中的字节流(下)—— FilterInputStream和FilterOutputStream

此外,既然是随机访问的,自然有文件内数据偏移量的维护。

public native long getFilePointer() throws IOException;

还可以通过这个方法得到offset。

对于文件的简要整理到这结束。

作者原创,难免有错误,欢迎读者热心评论留言指出,以免误导他人,谢谢!

此条目发表在 IO, Java, Java语言, 开发, 计算机技术 分类目录,贴了 , , , , 标签。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>