Performing Classic I/O 执行传统的I/O

Performing Classic I/O


Applications often input data for processing and output processing results. Data is input from a
file or some other source and is output to a file or some other destination. Java supports I/O via
the classic I/O APIs located in the java.io package and the new I/O APIs located in java.nio and
related subpackages (and java.util.regex). This chapter introduces you to the classic I/O APIs.

Note You’ve already experienced classic I/O in the context of Chapter 1’s Standard I/O coverage.


Working with the File API

使用FileAPI


Applications often interact with a filesystem, which is usually expressed as a hierarchy of files and

directories starting from a root directory.


Android and other platforms on which a virtual machine runs typically support at least one
filesystem. For example, a Unix/Linux (and Linux-based Android) platform combines all mounted
(attached and prepared) disks into one virtual filesystem. In contrast, Windows associates a separate

filesystem with each active disk drive.

Android 和其它虚拟机运行其上的平台典型地支持至少一个文件系统。

例如,Unix/Linux (和基于 Linux的 Android) 平台组合所有安装的(附加的和准备好的)

磁盘成一个虚拟文件系统。相反,Windows把单个文件系统和活动的磁盘驱动器联系起来。


Java offers access to the underlying platform’s available filesystem(s) via its concrete java.io.File
class. File declares the File[] listRoots() class method to return the root directories (roots) of

available filesystems as an array of File objects.


Note The set of available filesystem roots is affected by platform-level operations, such as inserting or
ejecting removable media, and disconnecting or unmounting physical or virtual disk drives.
Listing 11-1 presents a DumpRoots application that uses listRoots() to obtain an array of available

filesystem roots and then outputs the array’s contents.

注意 可用文件系统根集受平台级操作,如插入或弹出可移动媒介,和断开或解除挂载的物理和虚拟的磁盘器的影响。

Listing 11-1. Dumping Available Filesystem Roots to Standard Output
import java.io.File;
public class DumpRoots
{
public static void main(String[] args)
{
File[] roots = File.listRoots();
for (File root: roots)
System.out.println(root);
}
}
When I run this application on my Windows 7 platform, I receive the following output, which reveals
four available roots:
C:\
D:\
E:\
F:\
If I happened to run DumpRoots on a Unix or Linux platform, I would receive one line of output that
consists of the virtual filesystem root (/).
如果我碰巧在 Unix 或 Linux 平台上运行DumpRoots ,我会接收一行输出,包含虚拟文件系统根(/)。

Constructing File Instances

构建 File实例


Apart from using listRoots(), you can obtain a File instance by calling a File constructor such as
File(String pathname), which creates a File instance that stores the pathname string. The following
assignment statements demonstrate this constructor:
File file1 = new File("/x/y");
File file2 = new File("C:\\temp\\x.dat");


The first statement assumes a Unix/Linux platform, starts the pathname with root directory symbol
/, and continues with directory name x, separator character /, and file or directory name y. (It also
works on Windows, which assumes this path begins at the root directory on the current drive.)

第一个语句假定Unix/Linux平台,用根目录符号/开始路径名。


Note A path is a hierarchy of directories that must be traversed to locate a file or a directory. A pathname is
a string representation of a path; a platform-dependent separator character (such as the Windows backslash
[\] character) appears between consecutive names.


The second statement assumes a Windows platform, starts the pathname with drive specifier C:,
and continues with root directory symbol \, directory name temp, separator character \, and filename
x.dat (although x.dat might refer to a directory). (I could also use forward slashes on Windows.)

我也可以在Windows上使用斜杠。

Caution Always double backslash characters that appear in a string literal, especially when specifying
a pathname; otherwise, you run the risk of bugs or compiler error messages. For example, I doubled the
backslash characters in the second statement to denote a backslash and not a tab (\t) and to avoid a
compiler error message (\x is illegal).

警告


Each statement’s pathname is an absolute pathname, which is a pathname that starts with the
root directory symbol; no other information is required to locate the file/directory that it denotes.
In contrast, a relative pathname doesn’t start with the root directory symbol; it’s interpreted via
information taken from some other pathname.


Note The java.io package’s classes default to resolving relative pathnames against the current user
(also known as working) directory, which is identified by system property user.dir and which is typically
the directory in which the virtual machine was launched. (Chapter 7 showed you how to read system
properties via java.lang.System’s getProperty() method.)

注意 当前用户目录(也称做工作目录),用系统属性user.dir来标识并且典型地是虚拟机启动的目录。


File instances contain abstract representations of file and directory pathnames (these files or
directories may or may not exist in their filesystems) by storing abstract pathnames, which offer
platform-independent views of hierarchical pathnames. In contrast, user interfaces and operating
systems use platform-dependent pathname strings to name files and directories.

通过存储抽象路径名,File实例包含文件和目录路径名的抽象表示(这些文件或目录可能会或可能不会存在于文件系统中)。

提供独立于平台的层次路径名视图。相比之下,用户界面和操作系统使用与平台相关的目录路径名字符串来命名文件和目录

An abstract pathname consists of an optional platform-dependent prefix string, such as a disk

drive specifier—which is / for the Unix/Linux root directory or \\ for a Windows Universal Naming
Convention (UNC) pathname—and a sequence of zero or more string names. The first name in an
abstract pathname may be a directory name or, in the case of Windows UNC pathnames, a
hostname. Each subsequent name denotes a directory; the last name may denote a directory or a
file. The empty abstract pathname has no prefix and an empty name sequence.

抽象路径名包括一个可选的平台依赖前缀字符串,诸如一个磁盘驱动器符—代表Unix/Linu根目录的/ 代表Windows Universal Naming
Convention (UNC)路径名的\\
一系列零个或更多字符串名。

在一个抽象路径名中的第一个名字可以是一个目录名或,在Windows UNC情况下,是一个主机名。


The conversion of a pathname string to or from an abstract pathname is inherently platform dependent.
When a pathname string is converted into an abstract pathname, the names within this string may be
separated by the default name-separator character or by any other name-separator character that is
supported by the underlying platform. When an abstract pathname is converted into a pathname string,
each name is separated from the next by a single copy of the default name-separator character.

到(或从)一个抽象路径名的路径名的转换天生地平台依赖。当一个路径名字符串被转换成一个抽象路径名时,

字符串中的名字可以用默认名字分隔符或被由底层平台支持的其它任何名字分隔符分隔。当一个抽象路径名被转换成一个路径名字符串时,

每个名字由单个默认的名字分隔字符副本与下一个名字分隔。

Note The default name-separator character is defined by the system property file.separator and is
made available in File’s public static separator and separatorChar fields; the first field stores the
character in a java.lang.String instance and the second field stores it as a char value.

注意 默认的名称分隔字符由系统属性file.separator定义并且可在File的public static separator and separatorChar 字段中获得。


File offers additional constructors for instantiating this class. For example, the following constructors
merge parent and child pathnames into combined pathnames that are stored in File objects:


 File(String parent, String child) creates a new File instance from a parent
pathname string and a child pathname string.
 File(File parent, String child) creates a new File instance from a parent
pathname File instance and a child pathname string.

Each constructor’s parent parameter is passed a parent pathname, a string that consists of
all pathname components except for the last name, which is specified by child. The following
statement demonstrates this concept via File(String, String):
File file3 = new File("prj/books/", "ljfad3");


The constructor merges parent pathname prj/books/ with child pathname ljfad3 into pathname
prj/books/ljfad3. (If I had specified prj/books as the parent pathname, the constructor would have
added the separator character after books.)


Tip Because File(String pathname), File(String parent, String child), and File(File
parent, String child) don’t detect invalid pathname arguments (apart from throwing java.lang.
NullPointerException when pathname or child is null), you must be careful when specifying
pathnames. You should strive to only specify pathnames that are valid for all platforms on which the
application will run. For example,
instead of hard-coding a drive specifier (such as C:) in a pathname, use the
roots that are returned from listRoots(). Even better, keep your pathnames relative to the current user/
working directory (returned from the user.dir system property).

提示 不硬编码一个驱动器符。


Learning About Stored Abstract Pathnames

学习存储的抽象路径名


After obtaining a File object, you can interrogate it to learn about its stored abstract pathname by
calling the methods that are described in Table 11-1.


Table 11-1. File Methods for Learning About a Stored Abstract Pathname


Method Description
File getAbsoluteFile() Returns the absolute form of this File object’s abstract pathname. This
method is equivalent to new File(this.getAbsolutePath()).

返回这个File对象的抽象路径名的绝对形式。


String getAbsolutePath() Returns the absolute pathname string of this File object’s abstract pathname.
When it’s already absolute, the pathname string is returned as if by calling
getPath(). When it’s the empty abstract pathname, the pathname string of
the current user directory (identified via user.dir) is returned. Otherwise, the
abstract pathname is resolved in a platform-dependent manner. On Unix/
Linux platforms, a relative pathname is made absolute by resolving it against
the current user directory. On Windows platforms, the pathname is made
absolute by resolving it against the current directory of the drive named by the
pathname, or the current user directory when there is no drive.

File getCanonicalFile()  Returns the canonical (simplest possible, absolute, and unique) form of this
File object’s abstract pathname. This method throws java.io.IOException
when an I/O error occurs (creating the canonical pathname may require
filesystem queries); it equates to new File(this.getCanonicalPath()).

返回规范(简单的、绝对的、唯一)形式。

String getCanonicalPath() Returns the canonical pathname string of this File object’s abstract
pathname. This method first converts this pathname to absolute form when
necessary, as if by invoking getAbsolutePath(), and then maps it to its unique
form in a platform-dependent way. Doing so typically involves removing
redundant names such as . and .. from the pathname, resolving symbolic
links (on Unix/Linux platforms), and converting drive letters to a standard case
(on Windows platforms). This method throws IOException when an I/O error
occurs (creating the canonical pathname may require filesystem queries).


String getName() Returns the filename or directory name denoted by this File object’s abstract
pathname. This name is the last in a pathname’s name sequence. The empty
string is returned when the pathname’s name sequence is empty.


String getParent() Returns the parent pathname string of this File object’s pathname, or returns
null when this pathname doesn’t name a parent directory.


File getParentFile() Returns a File object storing this File object’s abstract pathname’s parent
abstract pathname; returns null when the parent pathname isn’t a directory.


String getPath() Converts this File object’s abstract pathname into a pathname string where
the names in the sequence are separated by the character stored in File’s
separator field. Returns the resulting pathname string.


boolean isAbsolute() Returns true when this File object’s abstract pathname is absolute; otherwise,
returns false when it’s relative. The definition of absolute pathname is system
dependent. On Unix/Linux platforms, a pathname is absolute when its prefix
is /. On Windows platforms, a pathname is absolute when its prefix is a drive
specifier followed by \ or when its prefix is \\.


String toString() A synonym for getPath().

Table 11-1 refers to IOException, which is the common exception superclass for those exception
classes that describe various kinds of I/O errors such as java.io.FileNotFoundException.
Listing 11-2 instantiates File with its pathname command-line argument and calls some of the File
methods described in Table 11-1 to learn about this pathname.
Listing 11-2. Obtaining Abstract Pathname Information
import java.io.File;
import java.io.IOException;
public class PathnameInfo
{
public static void main(final String[] args) throws IOException
{
if (args.length != 1)
{
System.err.println("usage: java PathnameInfo pathname");

return;
}
File file = new File(args[0]);
System.out.println("Absolute path = " + file.getAbsolutePath());
System.out.println("Canonical path = " + file.getCanonicalPath());
System.out.println("Name = " + file.getName());
System.out.println("Parent = " + file.getParent());
System.out.println("Path = " + file.getPath());
System.out.println("Is absolute = " + file.isAbsolute());
}
}
For example, when I specify java PathnameInfo . (the period represents the current directory on my
Windows 7 platform), I observe the following output:
Absolute path = C:\prj\dev\ljfad3\ch11\code\PathnameInfo\.
Canonical path = C:\prj\dev\ljfad3\ch11\code\PathnameInfo
Name = .
Parent = null
Path = .
Is absolute = false
This output reveals that the canonical pathname doesn’t include the period. It also shows that there
is no parent pathname and that the pathname is relative.
Continuing, I now specify java PathnameInfo c:\reports\2013\..\2012\February. This time, I
observe the following output:
Absolute path = c:\reports\2013\..\2012\February
Canonical path = C:\reports\2012\February
Name = February
Parent = c:\reports\2013\..\2012
Path = c:\reports\2013\..\2012\February
Is absolute = true
This output reveals that the canonical pathname doesn’t include 2013. It also shows that the
pathname is absolute.
For my final example, suppose I specify java PathnameInfo "" to obtain information for the empty
pathname. In response, this application generates the following output:
Absolute path = C:\prj\dev\ljfad3\ch11\code\PathnameInfo
Canonical path = C:\prj\dev\ljfad3\ch11\code\PathnameInfo
Name =
Parent = null
Path =
Is absolute = false
The output reveals that getName() and getPath() return the empty string ("") because the empty
pathname is empty.

Learning About a Pathname’s File or Directory

学习路径名的File和Directory


You can interrogate the filesystem to learn about the file or directory represented by a File object’s
stored pathname by calling the methods that are described in Table 11-2.
Table 11-2. File Methods for Learning About a File or Directory


Method Description
boolean exists() Returns true if and only if the file or directory denoted by this File object’s
abstract pathname exists.


boolean isDirectory() Returns true when this File object’s abstract pathname refers to an existing
directory.


boolean isFile() Returns true when this File object’s abstract pathname refers to an existing
normal file. A file is normal when it’s not a directory and satisfies other platform-
dependent criteria: it’s not a symbolic link or a named pipe, for example. Any
nondirectory file created by a Java application is guaranteed to be a normal file.


boolean isHidden() Returns true when the file denoted by this File object’s abstract pathname is
hidden. The exact definition of hidden is platform dependent. On Unix/Linux
platforms, a file is hidden when its name begins with a period character. On
Windows platforms, a file is hidden when it has been marked as such in the
filesystem.


long lastModified() Returns the time that the file denoted by this File object’s abstract pathname
was last modified, or 0 when the file doesn’t exist or an I/O error occurred during
this method call. The returned value is measured in milliseconds since the Unix
epoch (00:00:00 GMT, January 1, 1970).


long length() Returns the length of the file denoted by this File object’s abstract pathname.
The return value is unspecified when the pathname denotes a directory and will
be 0 when the file doesn’t exist.


Listing 11-3 instantiates File with its pathname command-line argument, and calls all of the File
methods described in Table 11-2 to learn about the pathname’s file/directory.


Listing 11-3. Obtaining File/Directory Information
import java.io.File;
import java.io.IOException;
import java.util.Date;


public class FileDirectoryInfo
{
public static void main(final String[] args) throws IOException
{
if (args.length != 1)
{
System.err.println("usage: java FileDirectoryInfo pathname");

return;
}
File file = new File(args[0]);
System.out.println("About " + file + ":");
System.out.println("Exists = " + file.exists());
System.out.println("Is directory = " + file.isDirectory());
System.out.println("Is file = " + file.isFile());
System.out.println("Is hidden = " + file.isHidden());
System.out.println("Last modified = " + new Date(file.lastModified()));
System.out.println("Length = " + file.length());
}
}
For example, suppose I have a three-byte file named x.dat. When I specify java FileDirectoryInfo
x.dat, I observe the following output:
About x.dat:
Exists = true
Is directory = false
Is file = true
Is hidden = false
Last modified = Mon Oct 14 15:31:04 CDT 2013
Length = 3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值