Thinking logic of computer programs (59) and thinking 59
The previous two sections show you how to read and write file content through a stream. This section describes operations on file metadata and directories.
File and directory operations are ultimately related to the operating system and file system. The implementations of different systems are different, but Java. io. the File class provides a unified interface. At the underlying layer, it calls the specific implementation of the operating system and the File system through local methods. In this section, we will introduce the File class.
Operations in the File class can be divided into three types:
- File metadata
- File Operations
- Directory operations
Before introducing these operations, let's take a look at the File construction method.
Constructor
File can represent both files and directories. Its main constructor methods include:
public File(String pathname)public File(String parent, String child)public File(File parent, String child)
It can be a pathname parameter, indicating the complete path, which can be a relative or absolute path. It can also be two parameters, indicating the parent of the parent directory and the child of the child.
The path in the File can exist or not exist.
Creating a File object through new does not actually create a File, but creates an object that represents a File or directory. After new, the path in the File object is unchangeable.
File metadata
File Name and Path
With a File object, you can obtain its File name and path information. The related methods include:
public String getName()public boolean isAbsolute()public String getPath()public String getAbsolutePath()public String getCanonicalPath() throws IOExceptionpublic String getParent()public File getParentFile()public File getAbsoluteFile()public File getCanonicalFile() throws IOException
GetName () returns the name of the file or directory, excluding the path name. IsAbsolute () determines whether the path in the File is an absolute path.
GetPath () returns the complete path name when constructing a File object, including the path and File name. GetAbsolutePath () returns the complete absolute path name. GetCanonicalPath () returns the standard complete path name. It removes redundant names in the path, such as ".", "...", and tracks soft connections (Unix system concepts. These three paths are easy to confuse. Let's look at an example to illustrate:
File f = new File("../io/test/students.txt");System.out.println(System.getProperty("user.dir"));System.out.println("path: " + f.getPath());System.out.println("absolutePath: " + f.getAbsolutePath());System.out.println("canonicalPath: " + f.getCanonicalPath());
Here, the relative path is used to construct the File object,... indicates the upper-level directory, and the output is:
/Users/majunchang/iopath: ../io/test/students.txtabsolutePath: /Users/majunchang/io/../io/test/students.txtcanonicalPath: /Users/majunchang/io/test/students.txt
The current directory is/Users/majunchang/io. getPath () returns the relative path used to construct the File object, while getAbsolutePath () returns the complete path, but contains the redundant path ".. /io/", while getCanonicalPath () removes the redundant path.
GetParent () returns the parent directory path, and getParentFile () returns the File object of the parent directory. Note that if the File object is a relative path, these methods may not get the parent directory, for example:
File f = new File("students.txt");System.out.println(System.getProperty("user.dir"));System.out.println("parent: " + f.getParent());System.out.println("parentFile: " + f.getParentFile());
Output:
/Users/majunchang/ioparent: nullparentFile: null
The return value of getParent () is null even if there is a parent directory. So how can we solve this problem? You can use the getAbsoluteFile () or getCanonicalFile () Methods to return a new File object. The new File objects use the return values of getAbsolutePath () and getCanonicalPath () as the parameter structures respectively. For example, modify the above Code:
File f = new File("students.txt");System.out.println(System.getProperty("user.dir"));System.out.println("parent: " + f.getCanonicalFile().getParent());System.out.println("parentFile: " + f.getCanonicalFile().getParentFile());
This time, we can get the parent directory, and the output is:
/Users/majunchang/ioparent: /Users/majunchang/ioparentFile: /Users/majunchang/io
The File class has four static variables, indicating the path separator. They are:
public static final String separatorpublic static final char separatorCharpublic static final String pathSeparatorpublic static final char pathSeparatorChar
Separator and separatorChar are file path delimiters. In Windows systems, they are generally "\", and in Linux systems, they are generally "/".
PathSeparator and pathSeparatorChar indicate separators in multiple file paths, such as separators in the environment variable PATH and in the Java class PATH variable classpath. When executing commands, the operating system looks for commands from the directory specified by PATH. When a class file is loaded during Java runtime, class files are searched from the PATH specified by classpath. In Windows, this Delimiter is generally ';'. in Linux, this Delimiter is generally ':'.
Basic File Information
In addition to the File name and path, the File object also has the following method to obtain the basic information of the File or directory:
// Whether the file or directory contains public boolean exists () // whether it is the directory public boolean isDirectory () // whether it is the file public boolean isFile () // The file length, the number of bytes public long length () // The last modification time. The number of milliseconds starting from the epoch is public long lastModified () // The last modification time. If the setting is successful, true is returned, otherwise, falsepublic boolean setLastModified (long time) is returned)
For the directory, the return value of the length () method is meaningless.
It should be noted that the File object does not return the creation time method, because the creation time is not a public concept, and Linux/Unix does not have the concept of creation time.
Security and permission information
Methods related to security and permissions in the File class include:
// Whether the object is a hidden public boolean isHidden () // whether the object can be executed public boolean canExecute () // whether the object can be read public boolean canRead () // whether the object can be written public boolean canWrite () // set the object to a read-only file public boolean setReadOnly () // modify the object read permission public boolean setReadable (boolean readable, boolean ownerOnly) public boolean setReadable (boolean readable) // modify the file write permission public boolean setWritable (boolean writable, boolean ownerOnly) public boolean setWritable (boolean writable) // modify the file executable permission public boolean setExecutable (boolean executable, boolean ownerOnly) public boolean setExecutable (boolean executable)
In the modification method, if the modification is successful, true is returned; otherwise, false is returned. In the permission setting method, if ownerOnly is true, it indicates that the permission is only for the owner. If false, it indicates that the permission is for all users. If no ownerOnly is specified, ownerOnly is equivalent to true.
File Operations
File Operations include creating, deleting, and renaming.
Create
Creating a File object does not actually create a File, but the method is as follows:
public boolean createNewFile() throws IOException
If the file is successfully created, true is returned. Otherwise, false is returned. The content of the newly created file is null. If the file already exists, it is not created.
The File object also has two static methods to create a temporary File:
public static File createTempFile(String prefix, String suffix) throws IOExceptionpublic static File createTempFile(String prefix, String suffix, File directory) throws IOException
The complete path name of a temporary file is specified and unique by the system. However, you can specify prefix, suffix, and directory through parameters. prefix is required, it must contain at least three characters. If suffix is null, the default value is ". tmp ", if directory is not specified or specified as null, the system default directory is used. Let's look at an example:
File file = File.createTempFile("upload_", ".jpg");System.out.println(file.getAbsolutePath());
Some running output on my computer is:
/var/folders/fs/8s4jdbj51jvcm7vc6lm_144r0000gn/T/upload_8850973909847443784.jpg
Delete
The File class is deleted as follows:
public boolean delete()public void deleteOnExit()
Delete: delete a file or directory. If the file or directory is deleted successfully, true is returned. Otherwise, false is returned. If the File is a directory and is not empty, the delete operation fails and false is returned. In other words, to delete a directory, delete all subdirectories and files in the directory first.
DeleteOnExit adds the File object to the list to be deleted and deletes it when the Java Virtual Machine Exits normally.
Rename
Method:
public boolean renameTo(File dest)
The dest parameter indicates the renamed file. Whether the renaming is successful depends on the system. If the renaming is successful, true is returned. Otherwise, false is returned.
Directory operations
When a File object represents a directory, you can perform directory-related operations, such as creating and traversing.
Create
There are two ways to create a directory:
public boolean mkdir()public boolean mkdirs()
They are all creating directories. true is returned for successful creation, and false is returned for failure. Note that if the directory already exists, the returned value is false. The difference between the two methods is that, if a middle parent directory does not exist, mkdir fails and false is returned, while mkdirs creates a required middle parent directory.
Traversal
You can use the following methods to access sub-directories and files in a directory:
public String[] list()public String[] list(FilenameFilter filter)public File[] listFiles()public File[] listFiles(FileFilter filter)public File[] listFiles(FilenameFilter filter)
They all return direct subdirectories or files, and do not return files in the subdirectories. List returns an array of File names, while listFiles returns an array of File objects. Both FilenameFilter and FileFilter are interfaces for filtering. The definition of FileFilter is as follows:
public interface FileFilter { boolean accept(File pathname);}
FilenameFilter is defined:
public interface FilenameFilter { boolean accept(File dir, String name);}
When traversing sub-directories and files, the FilenameFilter or FileFilter accept method is called for each file. Only when the accept method returns true will this sub-directory or file be included in the returned results.
The difference between FilenameFilter and FileFilter is that the accept method parameter of FileFilter has only one File object, while the accept method parameter of FilenameFilter has two. dir indicates the parent directory, and name indicates the subdirectory or File name.
Let's take a look at this example and list all the files suffixed with. txt in the current directory. The code can be:
File f = new File(".");File[] files = f.listFiles(new FilenameFilter(){ @Override public boolean accept(File dir, String name) { if(name.endsWith(".txt")){ return true; } return false; }});for(File file : files){ System.out.println(file.getCanonicalPath());}
We created an anonymous internal class object of FilenameFilter and passed it to listFiles.
With the Traversal method, we can easily perform recursive traversal to complete some more advanced functions.
For example, to calculate the size of all files in a directory (including subdirectories), the code can be:
public static long sizeOfDirectory(final File directory) { long size = 0; if (directory.isFile()) { return directory.length(); } else { for (File file : directory.listFiles()) { if (file.isFile()) { size += file.length(); } else { size += sizeOfDirectory(file); } } } return size;}
For another example, in a directory, to find all the files with the given file name, the code can be:
public static Collection<File> findFile(final File directory, final String fileName) { List<File> files = new ArrayList<>(); for (File f : directory.listFiles()) { if (f.isFile() && f.getName().equals(fileName)) { files.add(f); } else if (f.isDirectory()) { files.addAll(findFile(f, fileName)); } } return files;}
We have introduced the delete method of the File class. We mentioned that if you want to delete a directory but the directory is not empty, you must first clear the Directory and use the Traversal method, we can write a method to delete non-empty directories. The code can be:
public static void deleteRecursively(final File file) throws IOException { if (file.isFile()) { if (!file.delete()) { throw new IOException("Failed to delete " + file.getCanonicalPath()); } } else if (file.isDirectory()) { for (File child : file.listFiles()) { deleteRecursively(child); } if (!file.delete()) { throw new IOException("Failed to delete " + file.getCanonicalPath()); } }}
Summary
This section describes how to use the File class in Java to perform File and directory operations. The File class encapsulates the differences between the operating system and the File system and provides a unified API.
After understanding these operations, let's go back and look at the operations on the file content. We have introduced stream operations in addition to stream operations, such as random access and memory ing files, why do we still need these methods? What are their characteristics? In what scenarios? Let's continue exploring.
----------------
For more information, see the latest article. Please pay attention to the Public Account "lauma says programming" (scan the QR code below), from entry to advanced, ma and you explore the essence of Java programming and computer technology. Retain All copyrights with original intent.