21_IO流之File類
阿新 • • 發佈:2020-09-20
1. File類概述
File是檔案和目錄名的抽象表示. java中一切都是物件,File這個類就是檔案或者路徑的物件. 這些物件可以表示我們作業系統中的檔案和資料夾. 類中提供的方法可以對檔案進行操作, 建立, 刪除等. 後面學習的IO流可對File類的物件進行內容的填充和修改.
package java.io;
public class File
implements Serializable, Comparable<File>
{}
由類宣告我們可知, File類屬於java.io包下, 使用時需要導包. File是Object的直接子類, 實現了可序列, 可比較兩個介面.
2. File成員
2.1 成員變數
/** * The FileSystem object representing the platform's local file system.與作業系統相關的檔案系統 */ private static final FileSystem fs = DefaultFileSystem.getFileSystem(); /** * This abstract pathname's normalized pathname string. A normalized * pathname string uses the default name-separator character and does not * contain any duplicate or redundant separators. * * @serial */ private final String path; //路徑名 /** * Enum type that indicates the status of a file path. */ private static enum PathStatus { INVALID, CHECKED }; //路徑狀態 /** * The length of this abstract pathname's prefix, or zero if it has no * prefix. */ private final transient int prefixLength; //前輟長度 /** * The system-dependent default name-separator character. This field is * initialized to contain the first character of the value of the system * property {@code file.separator}. On UNIX systems the value of this * field is {@code '/'}; on Microsoft Windows systems it is {@code '\\'}. * * @see java.lang.System#getProperty(java.lang.String) */ public static final char separatorChar = fs.getSeparator(); //系統分割符
2.2 構造器(公開)
- 通過路徑名建立File物件
/** * Creates a new {@code File} instance by converting the given * pathname string into an abstract pathname. If the given string is * the empty string, then the result is the empty abstract pathname. * * @param pathname A pathname string * @throws NullPointerException * If the {@code pathname} argument is {@code null} */ public File(String pathname) { //通過路徑名 if (pathname == null) { throw new NullPointerException(); } this.path = fs.normalize(pathname); this.prefixLength = fs.prefixLength(this.path); }
- 根據父路徑名,建立子路徑
/**
* Creates a new {@code File} instance from a parent pathname string
* and a child pathname string.
*
* @param parent The parent pathname string
* @param child The child pathname string
* @throws NullPointerException
* If {@code child} is {@code null}
*/
public File(String parent, String child) {}
- 根據父路徑, 子路徑名建立路徑
/**
* Creates a new {@code File} instance from a parent abstract
* pathname and a child pathname string.
*
* @param parent The parent abstract pathname
* @param child The child pathname string
* @throws NullPointerException
* If {@code child} is {@code null}
*/
public File(File parent, String child)
- 根據URI建立
/**
* Creates a new {@code File} instance by converting the given
* {@code file:} URI into an abstract pathname.
*
*
* @param uri
* An absolute, hierarchical URI with a scheme equal to
* {@code "file"}, a non-empty path component, and undefined
* authority, query, and fragment components
*
*/
public File(URI uri){}
2.3 成員方法
2.3.1 獲取檔名
/**
* Returns the name of the file or directory denoted by this abstract
* pathname. This is just the last name in the pathname's name
* sequence. If the pathname's name sequence is empty, then the empty
* string is returned.
*
* @return The name of the file or directory denoted by this abstract
* pathname, or the empty string if this pathname's name sequence
* is empty
*/
public String getName() {
int index = path.lastIndexOf(separatorChar);
if (index < prefixLength) return path.substring(prefixLength);
return path.substring(index + 1);
}
2.3.2 獲取父檔名
/**
* Returns the pathname string of this abstract pathname's parent, or
* {@code null} if this pathname does not name a parent directory.
*
* <p> The <em>parent</em> of an abstract pathname consists of the
* pathname's prefix, if any, and each name in the pathname's name
* sequence except for the last. If the name sequence is empty then
* the pathname does not name a parent directory.
*
* @return The pathname string of the parent directory named by this
* abstract pathname, or {@code null} if this pathname
* does not name a parent
*/
public String getParent() {
int index = path.lastIndexOf(separatorChar);
if (index < prefixLength) {
if ((prefixLength > 0) && (path.length() > prefixLength))
return path.substring(0, prefixLength);
return null;
}
return path.substring(0, index);
}
2.3.3 獲取父檔案
/**
* Returns the abstract pathname of this abstract pathname's parent,
* or {@code null} if this pathname does not name a parent
* directory.
*
* <p> The <em>parent</em> of an abstract pathname consists of the
* pathname's prefix, if any, and each name in the pathname's name
* sequence except for the last. If the name sequence is empty then
* the pathname does not name a parent directory.
*
* @return The abstract pathname of the parent directory named by this
* abstract pathname, or {@code null} if this pathname
* does not name a parent
*
* @since 1.2
*/
public File getParentFile() {
String p = this.getParent();
if (p == null) return null;
return new File(p, this.prefixLength);
}
2.3.4 獲取路徑字串表示形式
/**
* Converts this abstract pathname into a pathname string. The resulting
* string uses the {@link #separator default name-separator character} to
* separate the names in the name sequence.
*
* @return The string form of this abstract pathname
*/
public String getPath() {
return path;
}
2.3.5 判斷是否為絕對路徑
/**
* Tests whether this abstract pathname is absolute. The definition of
* absolute pathname is system dependent. On UNIX systems, a pathname is
* absolute if its prefix is {@code "/"}. On Microsoft Windows systems, a
* pathname is absolute if its prefix is a drive specifier followed by
* {@code "\\"}, or if its prefix is {@code "\\\\"}.
*
* @return {@code true} if this abstract pathname is absolute,
* {@code false} otherwise
*/
public boolean isAbsolute() {
return fs.isAbsolute(this);
}
2.3.6 獲取絕對路徑字串表示
/**
* Returns the absolute pathname string of this abstract pathname.
*
* <p> If this abstract pathname is already absolute, then the pathname
* string is simply returned as if by the {@link #getPath}
* method. If this abstract pathname is the empty abstract pathname then
* the pathname string of the current user directory, which is named by the
* system property {@code user.dir}, is returned. Otherwise this
* pathname is resolved in a system-dependent way. On UNIX systems, a
* relative pathname is made absolute by resolving it against the current
* user directory. On Microsoft Windows systems, a relative pathname is made absolute
* by resolving it against the current directory of the drive named by the
* pathname, if any; if not, it is resolved against the current user
* directory.
*
* @return The absolute pathname string denoting the same file or
* directory as this abstract pathname
*
* @throws SecurityException
* If a required system property value cannot be accessed.
*
* @see java.io.File#isAbsolute()
*/
public String getAbsolutePath() {
return fs.resolve(this);
}
2.3.7 返回此抽象路徑的絕對形式
/**
* Returns the absolute form of this abstract pathname. Equivalent to
* <code>new File(this.{@link #getAbsolutePath})</code>.
*
* @return The absolute abstract pathname denoting the same file or
* directory as this abstract pathname
*
* @throws SecurityException
* If a required system property value cannot be accessed.
*
* @since 1.2
*/
public File getAbsoluteFile() {
String absPath = getAbsolutePath();
return new File(absPath, fs.prefixLength(absPath));
}
2.3.8 構造一個表示此抽象路徑名的file: URI。
/**
* Constructs a {@code file:} URI that represents this abstract pathname.
*
*
* @return An absolute, hierarchical URI with a scheme equal to
* {@code "file"}, a path representing this abstract pathname,
* and undefined authority, query, and fragment components
* @throws SecurityException If a required system property value cannot
* be accessed.
*
*/
public URI toURI() {
try {
File f = getAbsoluteFile();
String sp = slashify(f.getPath(), f.isDirectory());
if (sp.startsWith("//"))
sp = "//" + sp;
return new URI("file", null, sp, null);
} catch (URISyntaxException x) {
throw new Error(x); // Can't happen
}
}
2.3.9 是否可以讀取由此抽象路徑名錶示的檔案
/**
* Tests whether the application can read the file denoted by this
* abstract pathname. On some platforms it may be possible to start the
* Java virtual machine with special privileges that allow it to read
* files that are marked as unreadable. Consequently this method may return
* {@code true} even though the file does not have read permissions.
*
* @return {@code true} if and only if the file specified by this
* abstract pathname exists <em>and</em> can be read by the
* application; {@code false} otherwise
*
* @throws SecurityException
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkRead(java.lang.String)}
* method denies read access to the file
*/
public boolean canRead() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return fs.checkAccess(this, FileSystem.ACCESS_READ);
}
2.3.10 可寫(對比上一個方法)
public boolean canWrite() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
}
2.3.11 判斷此物件表示的檔案是否存在
/**
* Tests whether the file or directory denoted by this abstract pathname
* exists.
*
* @return {@code true} if and only if the file or directory denoted
* by this abstract pathname exists; {@code false} otherwise
*
* @throws SecurityException
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkRead(java.lang.String)}
* method denies read access to the file or directory
*/
public boolean exists() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
}
2.3.12 判斷此物件表示的是否是一個資料夾
/**
* Tests whether the file denoted by this abstract pathname is a
* directory.
*
* <p> Where it is required to distinguish an I/O exception from the case
* that the file is not a directory, or where several attributes of the
* same file are required at the same time, then the {@link
* java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
* Files.readAttributes} method may be used.
*
* @return {@code true} if and only if the file denoted by this
* abstract pathname exists <em>and</em> is a directory;
* {@code false} otherwise
*
*/
public boolean isDirectory() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
!= 0);
}
2.3.14 判斷是否為一個檔案
/**
* Tests whether the file denoted by this abstract pathname is a normal
* file. A file is <em>normal</em> if it is not a directory and, in
* addition, satisfies other system-dependent criteria. Any non-directory
* file created by a Java application is guaranteed to be a normal file.
*
* <p> Where it is required to distinguish an I/O exception from the case
* that the file is not a normal file, or where several attributes of the
* same file are required at the same time, then the {@link
* java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
* Files.readAttributes} method may be used.
*
* @return {@code true} if and only if the file denoted by this
* abstract pathname exists <em>and</em> is a normal file;
* {@code false} otherwise
*
* @throws SecurityException
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkRead(java.lang.String)}
* method denies read access to the file
*/
public boolean isFile() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
}
2.3.15 是否為隱藏檔案
/**
* Tests whether the file named by this abstract pathname is a hidden
* file. The exact definition of <em>hidden</em> is system-dependent. On
* UNIX systems, a file is considered to be hidden if its name begins with
* a period character ({@code '.'}). On Microsoft Windows systems, a file is
* considered to be hidden if it has been marked as such in the filesystem.
*
* @return {@code true} if and only if the file denoted by this
* abstract pathname is hidden according to the conventions of the
* underlying platform
*/
public boolean isHidden() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return false;
}
return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
}
2.3.16 記錄上次修改時間
/**
* Returns the time that the file denoted by this abstract pathname was
* last modified.
*
* @return A {@code long} value representing the time the file was
* last modified, measured in milliseconds since the epoch
* (00:00:00 GMT, January 1, 1970), or {@code 0L} if the
* file does not exist or if an I/O error occurs. The value may
* be negative indicating the number of milliseconds before the
* epoch
*
*/
public long lastModified() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return 0L;
}
return fs.getLastModifiedTime(this);
}
2.3.17 返回由此抽象路徑名錶示的檔案的長度
/**
* Returns the length of the file denoted by this abstract pathname.
* The return value is unspecified if this pathname denotes a directory.
*
* <p> Where it is required to distinguish an I/O exception from the case
* that {@code 0L} is returned, or where several attributes of the same file
* are required at the same time, then the {@link
* java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
* Files.readAttributes} method may be used.
*
* @return The length, in bytes, of the file denoted by this abstract
* pathname, or {@code 0L} if the file does not exist. Some
* operating systems may return {@code 0L} for pathnames
* denoting system-dependent entities such as devices or pipes.
*
* @throws SecurityException
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkRead(java.lang.String)}
* method denies read access to the file
*/
public long length() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return 0L;
}
return fs.getLength(this);
}
2.3.18 建立新檔案
/**
* Atomically creates a new, empty file named by this abstract pathname if
* and only if a file with this name does not yet exist. The check for the
* existence of the file and the creation of the file if it does not exist
* are a single operation that is atomic with respect to all other
* filesystem activities that might affect the file.
*
* @return {@code true} if the named file does not exist and was
* successfully created; {@code false} if the named file
* already exists
*
* @throws IOException
* If an I/O error occurred
*
* @throws SecurityException
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkWrite(java.lang.String)}
* method denies write access to the file
*
*/
public boolean createNewFile() throws IOException {
SecurityManager security = System.getSecurityManager();
if (security != null) security.checkWrite(path);
if (isInvalid()) {
throw new IOException("Invalid file path");
}
return fs.createFileExclusively(path);
}
2.3.19 刪除檔案
/**
* Deletes the file or directory denoted by this abstract pathname. If
* this pathname denotes a directory, then the directory must be empty in
* order to be deleted.
*
* @return {@code true} if and only if the file or directory is
* successfully deleted; {@code false} otherwise
*
* @throws SecurityException
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkDelete} method denies
* delete access to the file
*/
public boolean delete() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkDelete(path);
}
if (isInvalid()) {
return false;
}
return fs.delete(this);
}
2.3.20 在虛擬機器終止時刪除
/**
* Requests that the file or directory denoted by this abstract
* pathname be deleted when the virtual machine terminates.
* Files (or directories) are deleted in the reverse order that
* they are registered. Invoking this method to delete a file or
* directory that is already registered for deletion has no effect.
* Deletion will be attempted only for normal termination of the
* virtual machine, as defined by the Java Language Specification.
*
* @throws SecurityException
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkDelete} method denies
* delete access to the file
*
* @see #delete
*
* @since 1.2
*/
public void deleteOnExit() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkDelete(path);
}
if (isInvalid()) {
return;
}
DeleteOnExitHook.add(path);
}
2.3.21 物件中檔名組成的陣列
/**
* Returns an array of strings naming the files and directories in the
* directory denoted by this abstract pathname.
*
* <p> If this abstract pathname does not denote a directory, then this
* method returns {@code null}. Otherwise an array of strings is
* returned, one for each file or directory in the directory. Names
* denoting the directory itself and the directory's parent directory are
* not included in the result. Each string is a file name rather than a
* complete path.
*
* @return An array of strings naming the files and directories in the
* directory denoted by this abstract pathname. The array will be
* empty if the directory is empty. Returns {@code null} if
* this abstract pathname does not denote a directory, or if an
* I/O error occurs.
*
* @throws SecurityException
* If a security manager exists and its {@link
* SecurityManager#checkRead(String)} method denies read access to
* the directory
*/
public String[] list() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return null;
}
return fs.list(this);
}
2.3.22 此物件中檔案組成的陣列
/**
* Returns an array of abstract pathnames denoting the files in the
* directory denoted by this abstract pathname.
*
* @return An array of abstract pathnames denoting the files and
* directories in the directory denoted by this abstract pathname.
* The array will be empty if the directory is empty. Returns
* {@code null} if this abstract pathname does not denote a
* directory, or if an I/O error occurs.
*
* @throws SecurityException
* If a security manager exists and its {@link
* SecurityManager#checkRead(String)} method denies read access to
* the directory
*
* @since 1.2
*/
public File[] listFiles() {
String[] ss = list();
if (ss == null) return null;
int n = ss.length;
File[] fs = new File[n];
for (int i = 0; i < n; i++) {
fs[i] = new File(ss[i], this);
}
return fs;
}
2.3.23 建立由此抽象路徑名命名的目錄
/**
* Creates the directory named by this abstract pathname.
*
* @return {@code true} if and only if the directory was
* created; {@code false} otherwise
*
* @throws SecurityException
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkWrite(java.lang.String)}
* method does not permit the named directory to be created
*/
public boolean mkdir() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.createDirectory(this);
}
2.3.24 建立由此抽象路徑名命名的多級目錄
/**
* Creates the directory named by this abstract pathname, including any
* necessary but nonexistent parent directories. Note that if this
* operation fails it may have succeeded in creating some of the necessary
* parent directories.
*
* @return {@code true} if and only if the directory was created,
* along with all necessary parent directories; {@code false}
* otherwise
*
* @throws SecurityException
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkRead(java.lang.String)}
* method does not permit verification of the existence of the
* named directory and all necessary parent directories; or if
* the {@link
* java.lang.SecurityManager#checkWrite(java.lang.String)}
* method does not permit the named directory and all necessary
* parent directories to be created
*/
public boolean mkdirs() {
if (exists()) {
return false;
}
if (mkdir()) {
return true;
}
File canonFile = null;
try {
canonFile = getCanonicalFile();
} catch (IOException e) {
return false;
}
File parent = canonFile.getParentFile();
return (parent != null && (parent.mkdirs() || parent.exists()) &&
canonFile.mkdir());
}
2.3.25 重新命名
/**
* Renames the file denoted by this abstract pathname.
*
* @param dest The new abstract pathname for the named file
*
* @return {@code true} if and only if the renaming succeeded;
* {@code false} otherwise
*
* @throws SecurityException
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkWrite(java.lang.String)}
* method denies write access to either the old or new pathnames
*
* @throws NullPointerException
* If parameter {@code dest} is {@code null}
*/
public boolean renameTo(File dest) {
if (dest == null) {
throw new NullPointerException();
}
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
security.checkWrite(dest.path);
}
if (this.isInvalid() || dest.isInvalid()) {
return false;
}
return fs.rename(this, dest);
}
2.3.26 設定只讀
/**
* Marks the file or directory named by this abstract pathname so that
* only read operations are allowed. After invoking this method the file
* or directory will not change until it is either deleted or marked
* to allow write access. On some platforms it may be possible to start the
* Java virtual machine with special privileges that allow it to modify
* files that are marked read-only. Whether or not a read-only file or
* directory may be deleted depends upon the underlying system.
*
* @return {@code true} if and only if the operation succeeded;
* {@code false} otherwise
*
* @throws SecurityException
* If a security manager exists and its {@link
* java.lang.SecurityManager#checkWrite(java.lang.String)}
* method denies write access to the named file
*
* @since 1.2
*/
public boolean setReadOnly() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
}
if (isInvalid()) {
return false;
}
return fs.setReadOnly(this);
}
3. Demo
package f_io.a_file;
import java.io.File;
import java.io.IOException;
import java.net.URI;
/**
* 本類演示File類
*/
public class FileDemo {
public static void main(String[] args) throws IOException {
//構造器
// public File(String pathname)
File file = new File("a.txt");
//public File(String parent, String child)
File file2 = new File("test", "b.txt");
// public File(File parent, String child)
File file3 = new File("test");
File file4 = new File(file3, "c.txt");
//成員方法
// public String getName()
String name = file.getName();
System.out.println(name); //結果: a.txt
//public String getParent()
String parentName = file4.getParent();
System.out.println(parentName); //結果: test
//public File getParentFile()
File resultFile = file4.getParentFile();
System.out.println(resultFile.getName());//結果: test
// public String getPath()
String path = file.getPath();
System.out.println(path); //a.txt
// public boolean isAbsolute()
System.out.println(file.isAbsolute()); //false
//public String getAbsolutePath()
String absolutePath = file.getAbsolutePath();
System.out.println(absolutePath); //D:\java\code\note\javase\a.txt
//public File getAbsoluteFile()
File absFile = file.getAbsoluteFile();
System.out.println(absFile.getName()); //a.txt
// public URI toURI()
URI uri = file.toURI();
System.out.println(uri); //file:/D:/java/code/note/javase/a.txt
// public boolean canRead()
System.out.println(file.canRead()); //false
//public boolean canWrite()
System.out.println(file.canWrite());//false
// public boolean exists()
System.out.println(file.exists());//false
// public boolean isDirectory()
System.out.println(file.isDirectory());//false
//public boolean isFile()
System.out.println(file.isFile());//false
//public long lastModified()
System.out.println(file.lastModified()); //0
// public long length()
System.out.println(file.length());//0
// public boolean createNewFile()
//System.out.println(file.createNewFile()); //true
//public boolean delete()
//System.out.println(file.delete()); //true
//public void deleteOnExit()
//file.deleteOnExit();
//public String[] list()
//String[] list = file.list();
//public File[] listFiles()
//File[] files = file.listFiles();
//public boolean mkdir()
//System.out.println(file3.mkdir()); //true
// public boolean mkdirs()
//System.out.println(file3.mkdirs()); //true
//public boolean renameTo(File dest)
//System.out.println(file.renameTo(file4));
}
}
4. 小結
File是IO流操作的基礎, 有了檔案, 才可以進行內容的讀寫. 關於此部分知識只需要掌握一些基礎的檔案建立, 路徑寫法等知識, 及時查閱文件及可. 此外此部分中可以遞迴的查詢多級目錄下的檔案(清盤騷操作). 本片已經較為系統的列出了File類的操作, 已基本可以滿足需求.