The Java NIO Path interface and the Files class work with instances of files
- 2020-11-26 18:46:33
- OfStack
Path interface
1. Path refers to a sequence of directory names, which can be followed by a file name. When the first part of the path is the root part, it is the absolute path, such as/or C:\, and the accessible root part depends on the file system;
2. The path starting with the root part is an absolute path; otherwise, it is a relative path;
. 3, static Paths get method takes one or more string, the string between automatically use the default file system path separator connected (Unix is /, Windows \), which solved the problem of the cross-platform, then parse connected as a result, if not legal path is thrown InvalidPathException exception, otherwise it returns a Path object;
// Hypothesis is Unix File system
Path absolute = Paths.get("/home", "cat"); // An absolute path
Path relative = Pahts.get("ixenos", "config", "user.properties"); // Relative paths
4. Get Path object from String path
get can also get 1 whole path (that is, a single string of parts), such as reading a path from a configuration file:
String baseDir = properties.getProperty("base.dir");
// May gain /opt/ixenos or C:\Program Files\ixenos
Path basePath = Paths.get(baseDir);
5. Combine or parse paths
1) Calling ES29en. resolve(q) returns 1 Path as follows: If q is absolute, return q; otherwise, append path returns p/q or p\q
Path workRelative = Paths.get("work");
Path workPath = basePath.resolve(workRelative);
//resolve String parameters can also be accepted
Path workPath = basePath.resolve("work");
2) Calling ES42en.resolveSibling ("q") resolves the parent path o of the specified path p and produces the sibling path o/q
Path tempPath = workPath.resolveSibling("temp");
/*
if workPath is /opt/ixenos/work
So that will create /opt/ixenos/temp
*/
3) Call p. relativize(r) will generate a redundant path q, parse q will generate a relative path r, and finally r does not contain the intersection path with p
/*
pathA for /home/misty
pathB for /home/ixenos/config
now pathA right pathB When you do relativization, you create redundant paths
*/
Path pathC = pathA.relativize(pathB); // At this time pathC for ../ixenos/config
/*
normalize Method removes redundant parts
*/
Path pathD = pathC.normalize(); //pathD for /ixenos/config
4) toAbsolutePath will generate the absolute path of the given path, starting from the root part
5) The Path class also has a number of useful ways to break and combine paths, such as getParent, getFileName, getRoot// to get the root directory
6) Path has an toFile method for dealing with legacy File class, and File class has an toPath method
Files tools
1. Read and write files
Method signature:
static path write(Path path, byte[] bytes, OpenOption... options)
static path write(Path path, Iterable < ? extends CharSequence > lines, OpenOption... options)
Here is a list of the methods used below, see the API documentation for more...
OpenOption is an nio interface, and StandardOpenOption is its enum implementation class. Please check the API documentation for each enum instance function
/*
Files The simple method provided is suitable for processing medium-length text files
If the file you are processing is of a larger length, or 2 Base files, you should still use the classic IO flow
*/
// Read in all contents of the file byte In the array
byte[] bytes = Files.readAllBytes(path); // The incoming Path object
// You can then build strings based on the character set
String content = new String(bytes, charset);
// It can also be read directly as a sequence of rows
List<String> lines = Files.readAllLines(path, charset);
// Instead, you could write it 1 String to a file. Default is overwrite
Files.write(path, content.getBytes(charset)); // The incoming byte[]
// Append content, append according to parameters and other functions
Files.write(path, content.getBytes(charset), StandardOpenOption.APPEND); // Pass in the enumeration object and turn on the append switch
// will 1 A line String A collection of List Write to a file
Files.write(path, lines);
2. Copy, cut and delete
Method signature:
static path copy(Path source, Path target, CopyOption... options)
static path move(Path source, Path target, CopyOption... options)
static void delete(Path path) // If path does not have a file, an exception will be thrown. It is better to call the following
static boolean deleteIfExists(Path path)
Here is a list of the methods used below, see the API documentation for more...
CopyOption is an nio interface, and StandardCopyOption is its enum implementation class. Please check the API documentation for each enum instance function
One of these, ATOMIC_MOVE, can be filled in to ensure atomicity, either by successfully moving the file or by keeping the source file in place
// copy
Files.copy(fromPath, toPath);
// shear
Files.move(fromPath, toPath);
/*
If the above toPath Exists, then the operation fails,
To override, pass in parameters REPLACE_EXISTING
Also copy the file properties, pass in COPY_ATTRIBUTES
*/
Files.copy(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
Create files and directories
// Create a new directory, except at the end 1 Components, others must already exist
Files.createDirectory(path);
// Creates an intermediate directory in the path to create an intermediate widget that does not exist
Files.createDirectories(path);
/*
create 1 An empty file, checks that the file exists, and throws an exception if it does
Checking for file existence is atomic, so file creation cannot be performed during this process
*/
Files.createFile(path);
// Before adding / The suffix creates temporary files or temporary directories
Path newPath = Files.createTempFile(dir, prefix, suffix);
Path newPath = Files.createTempDirectory(dir, prefix);
4. Obtain file information
Skip the API document, or corejava page51
5. Iterate over the files in the directory
The old File class had two methods to get an array of strings made up of all the files in the directory, String[] list() and String[] list(FileFilter filter), but these methods performed very poorly when the directory contained a large number of files.
Reason analysis:
1 , //File class list All the files
public String[] list() {
SecurityManager security = System.getSecurityManager(); // File system permission access
if (security != null) {
security.checkRead(path);
}
if (isInvalid()) {
return null;
}
return fs.list(this); // The underlying call FileSystem the list
}
//FileSystem The abstract class list
//File Classes are defined in the fs Is made up of DefaultFileSystem Statically generated
private static final FileSystem fs = DefaultFileSystem.getFileSystem();
// So let's see 1 Under the DefaultFileSystem Class, discovery is generated 1 a WinNtFileSystem object
class DefaultFileSystem {
/**
* Return the FileSystem object for Windows platform.
*/
public static FileSystem getFileSystem() {
return new WinNTFileSystem();
}
}
// while WinNtFileSystem Class inherited from FileSystem Abstract class, here we mainly look at its list(File file) methods
@Override
public native String[] list(File f);
/* We can see that this is a native Method, description list The operation is controlled by the operating system's file system, and the performance of this method can be very poor when the directory contains a large number of files.
So instead of saying, NIO the Files The class design newDirectoryStream(Path dir) And its overloaded methods, will generate Iterable Object (available foreach Iteration) *///~
2 , // The callback filter
public String[] list(FilenameFilter filter) { // Interface callbacks are used
String names[] = list(); // call list all
if ((names == null) || (filter == null)) {
return names;
}
List<String> v = new ArrayList<>();
for (int i = 0 ; i < names.length ; i++) {
if (filter.accept(this, names[i])) { // The callback FilenameFileter The object's accept methods
v.add(names[i]);
}
}
return v.toArray(new String[v.size()]);
}
This is where the high tech comes in -- Files gets an iterable directory stream,
Pass in 1 directory Path, walk through descendant directory return 1 directory Path Stream, note that all Path involved here are directories and not files!
Therefore, the Files class designed newDirectoryStream(Path dir) and its overloaded methods to generate Iterable objects (foreach iterations are available)
Traverse the directory to obtain an iteratable descendant file set
CODE_TAG_REPLACE_MARK_0 |
CODE_TAG_REPLACE_MARK_1
Opens a directory, returning a
CODE_TAG_REPLACE_MARK_2
to iterate over all entries in the directory.
|
CODE_TAG_REPLACE_MARK_0 |
CODE_TAG_REPLACE_MARK_4
Opens a directory, returning a
CODE_TAG_REPLACE_MARK_2
to iterate over the entries in the directory.
|
CODE_TAG_REPLACE_MARK_0 | CODE_TAG_REPLACE_MARK_7 |
Returns a directory stream, which can be viewed as a collection of Iterable implementations that holds all of Path,
Therefore, we can use iterator or foreach iteration, but we should be careful not to use invoke and another Iterator:
While DirectoryStream extends Iterable, it is not a general-purpose Iterable as it supports only a single Iterator; invoking the iterator method to obtain a second or subsequent iterator throws IllegalStateException.
Example:
try(DirectoryStream<Path> entries = Files.newDirectoryStream(dir))
{
for(Path entry : entries)
{
...
}
}
You can pass in the glob parameter, that is, using glob mode to filter files (instead of list(FileFilter filter)) :
newDirectoryStream(Path dir, String glob) note the String type
String baseDir = properties.getProperty("base.dir");
// May gain /opt/ixenos or C:\Program Files\ixenos
Path basePath = Paths.get(baseDir);
0
glob mode
The so-called glob pattern refers to the simplified regular expression used by shell.
1. Asterisk * matches 0 or more characters in the path component; For example, *.java matches all Java files in the current directory
2. Two asterisks ** match 0 or more characters across directory boundaries; For example, **.java matches Java files in all subdirectories
3. Question mark (?) Matches only 1 character; For example the & # 63; The & # 63; The & # 63; The & # 63; .java matches Java files of all 4 characters, excluding extensions; Using the & # 63; Because * is a wildcard and does not specify a number
4. [...]. To match a set of characters, you can use the line [0-9] and the inverse character [!0-9]; For example, Test[0-9ES238en-ES239en].java matches ES241en.ES242en. Suppose x is one decimal number, [0-9ES244en-ES245en] matches a single character number in decimal, such as B (decimal 106 is case-insensitive).
If a short underscore is used in square brackets to separate two characters, it means that anything within those two characters can match (for example, [0-9] means matching all Numbers from 0 to 9).
5. {... } matches one of multiple options separated by commas; For example *.{java,class} matches all Java files and class class files
6.\ Escape characters in any of the above modes; For example, *\* matches all files in subdirectories whose filenames contain *, here escaped with **, followed by 0 or more characters matched
The following is the Glob pattern summarized by netizens:
Glob模式 | 描述 |
---|---|
*.txt | 匹配所有扩展名为.txt的文件 |
*.{html,htm} | 匹配所有扩展名为.html或.htm的文件。{ }用于组模式,它使用逗号分隔 |
?.txt | 匹配任何单个字符做文件名且扩展名为.txt的文件 |
. | 匹配所有含扩展名的文件 |
C:\Users\* | 匹配所有在C盘Users目录下的文件。反斜线“\”用于对紧跟的字符进行转义 |
/home/** | UNIX平台上匹配所有/home目录及子目录下的文件。**用于匹配当前目录及其所有子目录 |
[xyz].txt | 匹配所有单个字符作为文件名,且单个字符只含“x”或“y”或“z”3种之1,且扩展名为.txt的文件。方括号[]用于指定1个集合 |
[a-c].txt | 匹配所有单个字符作为文件名,且单个字符只含“a”或“b”或“c”3种之1,且扩展名为.txt的文件。减号“-”用于指定1个范围,且只能用在方括号[]内 |
[!a].txt | 匹配所有单个字符作为文件名,且单个字符不能包含字母“a”,且扩展名为.txt的文件。叹号“!”用于否定 |
Isn't iterating through the set of all the descendants of a directory nice enough? Let's go through all the descendants of a directory (including directories and files) directly.
We can call the walkFileTree method of the Files class and pass in an object of the FileVisitor interface type (there are more methods in API for you to find...).
String baseDir = properties.getProperty("base.dir");
// May gain /opt/ixenos or C:\Program Files\ixenos
Path basePath = Paths.get(baseDir);
1
So let's summarize 1,
Files.newDirectoryStream(Path dir) returns 1 iterable descendant file set after traversal;
Files.walkFileTree(Path dir, FileVisitor fv) is a process of traversing the descendant directories and files;
ZIP file system
As you know above, the Paths class looks for a path in the default file system, which is a file on the user's local disk.
In fact, we can have other file systems, such as the ZIP file system.
String baseDir = properties.getProperty("base.dir");
// May gain /opt/ixenos or C:\Program Files\ixenos
Path basePath = Paths.get(baseDir);
2
The above code creates an ES300en-based file system that contains all the files in the ZIP document.
1) If you know the file name (String type), it is easy to copy the file from the ZIP document:
Files.copy(fs.getPath(fileName), targetPath);
Q: ES310en.getPath USES the ZIP file system for getPath. Can the default file system be called?
A: can. The FileSystem class has a static getDefault() method that returns a default file system object, which can also be named getPath.
Specific getPath(String name) is traversal or random access, free to see the source code implementation.
2) To list all the files in the ZIP document, you can also traverse the file tree with walkFileTree
String baseDir = properties.getProperty("base.dir");
// May gain /opt/ixenos or C:\Program Files\ixenos
Path basePath = Paths.get(baseDir);
4