Java的IO系统(1) - 概述
输入输出是一门语言要提供的基本功能,Java从最早的1.0版本就提供了相对完善的IO能力。这篇开始我们简单介绍一下Java的IO系统。
Java到目前提供过两套IO模型,第一套是自创建Java之初就有的基于流的处理API,第二套是从1.4开始有的NIO。
不要把文件流和Java8提供的集合流混淆
下面是java.io包中定义的IO类(竖向字母序排列):
BufferedInputStream | FileWriter | PipedOutputStream |
BufferedOutputStream | FilterInputStream | PipedReader |
BufferedReader | FilterOutputStream | PipedWriter |
BufferedWriter | FilterReader | PrintStream |
ByteArrayInputStream | FilterWriter | PrintWriter |
ByteArrayOutputStream | InputStream | PushbackInputStream |
CharArrayReader | InputStreamReader | PushbackReader |
CharArrayWriter | LineNumberReader | RandomAccessFile |
Console | ObjectInputStream | Reader |
DataInputStream | ObjectInputStream.GetField | SequenceInputStream |
DataOutputStream | ObjectOutputStream | SerializablePermission |
File | ObjectOutputStream.PutField | StreamTokenizer |
FileDescriptor | ObjectStreamClass | StringReader |
FileInputStream | ObjectStreamField | StringWriter |
FileOutputStream | OutputStream | Writer |
FilePermission | OutputStreamWriter | |
FileReader | PipedlnputStream |
java.io包还有两个过期类:LineNumberInputStream 和 StringBufferInputStream。下面是包中的接口:
Closeable | FileFilter | ObjectInputValidation |
DataInput | FilenameFilter | ObjectOutput |
DataOutput | Flushable | ObjectStreamConstants |
Externalizable | ObjectInput | Serializable |
可见java.io包定义了很多类和接口。
io包里大多数类都是处理流的,也就是处理文件内容的,不过用的最多的java.io.File类却不是,它是操作文件目录或状态信息的,比如创建时间、权限、目录等。
java8以后常用Path类或Files类代替它
下面这段代码使用了大部分常用方法:
public static void main (String args[]) {
File f1 = new File ("...") ;
p("File Name:" + f1.getName ()) ; // 这里用p方法代替打印,所以你要先定义p方法
p("Path: " + f1.getPath()) ;
p("Abs Path: " + f1.getAbsolutePath()) ;
p("Parent: " + f1.getParent()) ;
p(f1.exists() ? "exists" : "does not exist") ;
p(f1.canWrite() ? "is writeable": "is not writeable") ;
p(f1.canRead() ? "is readable" : "is not readable") ;
p("is " +(f1.isDirectory() ? "": "not" + " a directory")) ;
p(f1.isFile() ? "is normal file" : "might be a named pipe") ; // 如果不是文件 可能是目录、外盘或管道,或者路径有误
p(f1.isAbsolute() ? "is absolute" : "is not absolute") ;
p("File last modified: " + f1.lastModified() ) ;
p("File size: " + f1.length()+ " Bytes") ;
}
File还提供了两个返回boolean的实例方法:renameTo(File newName) 和 delete()。第一个用于重命名,第二个是删除文件或目录,如果是目录必须为空才能成功删除。 如果想查看目录下的内容,可以使用listFiles()方法,它会以数组形式列出目录中的全部子目录和文件,通过上面使用的方法可以判断是文件还是目录。listFiles还有两个带参数的重载java.io.File#listFiles(java.io.FilenameFilter) 和 java.io.File#listFiles(java.io.FileFilter),不过用处不大。
Java7开始提供了toPath()方法将File实例转为Path实例。Path位于java.nio.file包中,是NIO的组成部分。
从Java7开始也提供了增强的try-with-resources语句,可以帮我们管理文件流的关闭。
在Java7以前,创建的流必须明确关闭,不然就可能引起内存泄漏。固定的做法就是放在try-finally块中。但是现在不用了,只要放在try后面的括号中就行了(这时候可以没有catch和finally块)。可以作为资源的对象必须实现java.io.Closeable或java.lang.AutoCloseable接口(实际上必须实现第二个接口,不过第一个接口也继承了第二个接口)。
