Chapters
Before we discuss File and Files Class and Path Interface, we need to understand pathnames first. Pathnames can be relative or absolute. Absolute pathnames start with the "root" directory. In UNIX or UNIX-like systems, the root directory is "/". For example, /home or /home/user
On Windows, the root directory is "drive-name:\". For example, C:\Users\ or C:\Users\user1\Desktop
Relative pathnames are relative to a working or current directory. For example, On windows, you're using command prompt and the current directoy where the command prompt is working on is in C:\Users\user1\Desktop\folder1. Then you want to delete a text file named as "txt1.txt" in folder1, since your working directory is folder1, just type this command: del txt1.txt
"del" is the command and "txt1.txt" is the relative pathname.
As you can see, relative pathname doesn't need to start from the root directory/file. For example, If your working directory is in C:\Users\user1\Desktop and you want to delete a text file named as "txt1.txt" in folder1 then, type this command: del folder1\txt1.txt
Note: Forward(/) and back(\) slashes are used in different types of pathnames. In UNIX, UNIX-like systems or URLs, forward(/) slash is used. On windows, back(\) slash is used. Though, forward(/) slash may work with some Windows systems.
"." represents current directory whereas ".." represents parent directory. "." is more useful for UNIX than Windows System. "." is used with UNIX to do some operation. For example, if we want to run executable in a current directory, we need to use "." to specify the current directory. UNIX command shell doesn't look for executables in current directory for security reasons, I think.
We can use the ".." to move down to a parent directory. For example, on Windows, the pathname "C:\Users\User1\Desktop\folder1\.." is equivalent to "C:\Users\User1\Desktop". You can try this example on the command prompt using the "cd" command.
The File class is a class that is located in java.io package. It manages file interactions between java application and computers. We can use this class to delete, rename and get the path of a file in abstract or string form. In this tutorial we will discusss some methods that we can use to interact with files in our hard disk/drive.
File class has four constructors. These two are commonly used. For the sake of simplicity, we will use this constructor in this tutorial.
The File class has static fields that represent separators. There are two types of separators: separator and path separator. Separator or the forward(/) slash for UNIX and back(\) slash for Windows, separates directories in a path. path separator or colon(:) for UNIX and semi-colon(;) for Windows, separates path to create a list of paths. Separators in java can be in char or String form.
e.g.
Note: Separator fields are system-dependent. It means, the separators that the fields return are based on operating system. For example, on Windows, File.separator returns back(\) slash.
This method returns true if the file or directory denoted by this abstract pathname exists. Otherwise, returns false. Hidden files don't affect the functionality of this method.
File class has methods that we can use to get a path that represents a file or directory. getAbsoluteFile() and getCanonicalFile() return a File type with pathname in either absolute or canonical format. getAbsolutePath() and getCanonicalPath() return a pathname in String form in either absolute or canonical format. getPath() returns a pathname in String form without any additional formatting. Canonical path is a path which symbols like "." and ".." and other problems like redundant name elements are resolved.
getName() returns the name of a file or directory. getParent() returns a String type pathname of a parent directory of a file or directory. getParentFile() returns a File type of a parent directory.
delete() method 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.
Note: files deleted by the delete() method wouldn't go to the trash/recycle bin. Use moveToTrash() method in Desktop class to move a file to trash/recycle bin.
renameTo() method renames the file denoted by this abstract pathname. Many aspects of the behavior of this method are inherently platform-dependent: The rename operation might not be able to move a file from one filesystem to another, it might not be atomic, and it might not succeed if a file with the destination abstract pathname already exists. The return value should always be checked to make sure that the rename operation was successful.
list() method returns an array of String of names of files and directories in a directory whereas listFiles() returns an array of File of names of files and directories in a directory. list() and listFiles() has other forms but for the sake of simplicity, we're just gonna discuss list() and listFiles().
mkdir creates a directory and returns true if the operation is successful. mkdirs() creates a directory and other necessary but nonexistent parent directories along the way. return true if the operation is successful. otherwise, returns. Note that if this operation fails it may have succeeded in creating some of the necessary parent directories.
This method converts abstract pathname to a Path type that is associated with the default FileSystem.
Path interface stores a path of a file. This interface is similar to the The File class. Path interface is used for the features available in java.nio.file package that require a Path interface, whereas File class is used for general-purpose file path storage.
To wrap a file path into a Path object. We can wrap the file path in a File object first then convert the File object to Path object by using toPath() method. Second is to use the get() method in Paths class.
getFileName() method returns the file name of a file wrapped in Path object. getName() method returns a name element of a path denoted by an index.
normalize() method removes the symbols "." and ".." and redundant name elements in a path. The precise definition of this method is implementation dependent but in general it derives from this path, a path that does not contain redundant name elements. In many file systems, the "." and ".." are special names used to indicate the current directory and parent directory.
resolve() method resolves this path against the given path. This method has a parameter that could be a Path or String type. If the given path is an absolute path then, this method will return the given path as a result. If the given path is empty then, it returns this path. If the given path is not absolute then, this path is considered as a directory and it's resolved against the given path.
resolveSibling() method resolves the given path against this path's parent path. This has similarities with resolve() method.
This method is the inverse of resolution like resolve(). This method attempts to construct a relative path that when resolved against this path, yields a path that locates the same file as the given path.This method creates a relative path when this path is resolved against the given path.
Both paths must have root components if one of them has one and the roots of both paths must be the same. A relative path cannot be constructed if only one of the paths have a root component. It can also be constructed if both paths don't have root component.
Where both paths have a root component then it is implementation dependent if a relative path can be constructed. If this path and the given path are equal then an empty path is returned.
This method converts Path type to File type. This method returns a File type that is the converted Path type.
Files class is located at java.nio.file package. This class consists exclusively of static methods that operate on files, directories, or other types of files. We will discuss some methods in this class that may be useful for us.
Symbolic links are special type of files that serve as links to files. Any operation done to a symbolic link will be done to the file that is link to that symbolic link, except for deleting and renaming. Deleting or renaming a symbolic link won't delete or rename the file that is linked to the symbolic link.
There are two types of symbolic links: soft link and hard link. Let's start with the soft link. To create a soft link we will use the Files.createSymbolicLink() method.
The link parameter is the path of the symbolic link, target parameter is the path of the file that is going to be linked with the symbolic link and the attrs parameter is optional attributes to set atomically when creating the link.
Note: If you encounter a FileSystemException like this: java.nio.file.FileSystemException: c:\test\myLinks\testLink.txt:
A required privilege is not held by the client.
If you're using Windows, try running your cmd or IDE as administrator.
Note: Some operating system invalidates symbolic links when they're moved to a different root. For example, symbolic links from C: drive will be invalidated if they are moved to F: drive. If symbolic links are invalidated they become empty directories if the symbolic links are directories. Otherwise, they become empty files.
Next, let's create a hard link. Hard link is similar to soft link but more restrictive. These are the restrictions of hard link according to this article
The existing parameter is the existing target file and the link parameter is the hard link.
Note: If you encounter a FileSystemException like this: java.nio.file.FileSystemException: c:\test\myLinks\testLink.txt:
A required privilege is not held by the client.
If you're using Windows, try running your cmd or IDE as administrator.
If we want to get the path of the linked file in a symbolic link, we can use the readSymbolicLink() method.
Some methods doesn't follow symbolic link by default like
Although, this method has second form which can enable following of symbolic links
In the
What do you mean following symbolic links? you might ask. When a method follows a symbolic link, it will access the file that is linked to that symbolic link. For example,
When a method doesn't follow a symbolic link, it will access the symbolic link and not the linked file in the symbolic link.
Note: Beware of circular reference. Circular reference is a scenario where the target of a link points back to the original link. This often happens when linking directories. For example, myDir is a directory which is linked to dirA symbolic link, which is linked to dir2 symbolic link and dir2 has subdirectory dir3 which is a symbolic link pointing to myDir.
Circular references can cause havoc when a program is recursively walking a directory structure. However, this scenario has been accounted for and will not cause your program to loop infinitely.
This method copies a file to a target file. This method has three forms but we're gonna focus on one form:
source parameter is the file source, target parameter is the destination and options parameter is a number of options provided by StandardCopyOption and LinkOption. CopyOption is a superinterface of both classes.
You may include any of these options in this method:
REPLACE_EXISTING
COPY_ATTRIBUTES
NOFOLLOW_LINKS
This example demonstrates
If we use COPY_ATTRIBUTES but the target file already exists, Files.copy() will throw FileAlreadyExistsException.
This methods delete a file. A directory must be empty to be deleted. Otherwise, DirectoryNotEmptyException will be thrown. An implementation may require to examine the file to determine if the file is a directory. Consequently, these methods may not be atomic with respect to other file system operations.
Note: files deleted by these methods wouldn't go to the trash/recycle bin. Use moveToTrash() method in Desktop class to move a file to trash/recycle bin.
This method moves a file to a target file. failing if the target file exists except if the source and target are the same file, in which case this method has no effect. For a non-empty directory with standard files, moving may involve copying rather than moving directories and this can be done using the copy method in conjunction with the Files.walkFileTree utility method. Thus, Files/directories in the current directory will be moved to the new directory.
We may include these options in this method:
REPLACE_EXISTING
ATOMIC_MOVE
This method traverses a file tree. This method has two forms but we're going to focus on this form:
start parameter is the starting directory and the visitor parameter is a FileVisitor type. We need to create our FileVisitor implementation to manage files in a file tree during the operation. In this tutorial, we're going to create a simple implementation of FileVisitor so, SimpleFileVisitor will suffice.
By default this method form doesn't follow symbolic links. The second form of this method has a parameter that can enable following of symbolic links:
The
The difference between FileVisitor and SimpleFileVisitor is that SimpleFileVisitor doesn't require all of its methods to be overriden whereas FileVisitor requires all of its methods to be overriden. We also need FileVisitResult 'cause methods of SimpleFileVisitor and FileVisitor require FileVisitResult as return type.
In this tutorial, we're going to do an attempt to delete a non-empty directory. To do that, we need to delete all the files in the directory first before deleting the directory.
There are two methods that are not overriden here but they can be overriden: preVisitDirectory() and visitFileFailed(). Read the FileVisitor documentation for more details.
- Pathnames
- File Class
- File Class Constructors
- Separator Fields
- exists() Method
- getAbsolutePath/File(), getCanonicalPath/File() and getPath() Methods
- getName(), getParent() and getParentFile() Methods
- isDirectory(), isFile() and isHidden() Methods
- delete() Method
- renameTo() Method
- list() and listFiles() Methods
- mkdir() and mkdirs() Methods
- toPath() Method
- Path Interface
- getFileName() and getName() Methods
- normalize() Method
- resolve() Method
- resolveSibling() Method
- relativize() Method
- toFile() Method
- Files Class
Pathnames
Before we discuss File and Files Class and Path Interface, we need to understand pathnames first. Pathnames can be relative or absolute. Absolute pathnames start with the "root" directory. In UNIX or UNIX-like systems, the root directory is "/". For example, /home or /home/user
On Windows, the root directory is "drive-name:\". For example, C:\Users\ or C:\Users\user1\Desktop
Relative pathnames are relative to a working or current directory. For example, On windows, you're using command prompt and the current directoy where the command prompt is working on is in C:\Users\user1\Desktop\folder1. Then you want to delete a text file named as "txt1.txt" in folder1, since your working directory is folder1, just type this command: del txt1.txt
"del" is the command and "txt1.txt" is the relative pathname.
As you can see, relative pathname doesn't need to start from the root directory/file. For example, If your working directory is in C:\Users\user1\Desktop and you want to delete a text file named as "txt1.txt" in folder1 then, type this command: del folder1\txt1.txt
Note: Forward(/) and back(\) slashes are used in different types of pathnames. In UNIX, UNIX-like systems or URLs, forward(/) slash is used. On windows, back(\) slash is used. Though, forward(/) slash may work with some Windows systems.
"." and ".." Symbols
"." represents current directory whereas ".." represents parent directory. "." is more useful for UNIX than Windows System. "." is used with UNIX to do some operation. For example, if we want to run executable in a current directory, we need to use "." to specify the current directory. UNIX command shell doesn't look for executables in current directory for security reasons, I think.
We can use the ".." to move down to a parent directory. For example, on Windows, the pathname "C:\Users\User1\Desktop\folder1\.." is equivalent to "C:\Users\User1\Desktop". You can try this example on the command prompt using the "cd" command.
File Class
The File class is a class that is located in java.io package. It manages file interactions between java application and computers. We can use this class to delete, rename and get the path of a file in abstract or string form. In this tutorial we will discusss some methods that we can use to interact with files in our hard disk/drive.
File Class Constructors
File class has four constructors. These two are commonly used. For the sake of simplicity, we will use this constructor in this tutorial.
Separator Fields
The File class has static fields that represent separators. There are two types of separators: separator and path separator. Separator or the forward(/) slash for UNIX and back(\) slash for Windows, separates directories in a path. path separator or colon(:) for UNIX and semi-colon(;) for Windows, separates path to create a list of paths. Separators in java can be in char or String form.
e.g.
String path = "C:"+File.separator+"Users"+File.separator+"User1";
Note: Separator fields are system-dependent. It means, the separators that the fields return are based on operating system. For example, on Windows, File.separator returns back(\) slash.
exists() Method
This method returns true if the file or directory denoted by this abstract pathname exists. Otherwise, returns false. Hidden files don't affect the functionality of this method.
import java.io.File; public class SampleClass{ public static void main(String[] args){ //Backslash(\) has special meaning in //java so, we need to escape it by //adding another backslash File file = new File("C:\\test\\test.txt"); if(file.exists()) System.out.println("File Exists!"); else System.out.println("File Doesn't Exist!"); } } Result File Exists!If you have a "test" directory in C: drive and there's a "test.txt" in that directory then, file.exists() would return true if no exception occurs. Otherwise, the file simply doesn't exist or an exception occurs.
getAbsolutePath/File(), getCanonicalPath/File() and getPath() Methods
File class has methods that we can use to get a path that represents a file or directory. getAbsoluteFile() and getCanonicalFile() return a File type with pathname in either absolute or canonical format. getAbsolutePath() and getCanonicalPath() return a pathname in String form in either absolute or canonical format. getPath() returns a pathname in String form without any additional formatting. Canonical path is a path which symbols like "." and ".." and other problems like redundant name elements are resolved.
import java.io.File; import java.io.IOException; public class SampleClass{ public static void main(String[] args) throws IOException{ //The pathname here is a relative pathname //there should be "folder1" beside the .class //file of this source code File fileOne = new File("folder1\\testfolder\\.."); if(fileOne.exists()){ String pathname = fileOne.getAbsolutePath(); System.out.println("Absolute Path: " + pathname); pathname = fileOne.getCanonicalPath(); System.out.println("Canonical Path: " + pathname); pathname = fileOne.getPath(); System.out.println("Path: " + pathname); System.out.println(); System.out.println("get File type with canonical format"); File fileTwo = fileOne.getCanonicalFile(); System.out.println("Path: " + fileTwo.getPath()); } else System.out.println("File Doesn't Exist!"); } } Result(Yours may be different) Absolute Path: C:\Users\Admin\Desktop\aaa\SampleClass\folder1\testfolder\.. Canonical Path: C:\Users\Admin\Desktop\aaa\SampleClass\folder1 Path: folder1\testfolder\.. get File type with canonical format Path: C:\Users\Admin\Desktop\aaa\SampleClass\folder1
getName(), getParent() and getParentFile() Methods
getName() returns the name of a file or directory. getParent() returns a String type pathname of a parent directory of a file or directory. getParentFile() returns a File type of a parent directory.
import java.io.File; public class SampleClass{ public static void main(String[] args){ File file = new File("C:\\test\\test.txt"); if(file.exists()){ String fileName = file.getName(); System.out.println("File Name: " + fileName); String parentPath = file.getParent(); System.out.println("Parent Path: " + parentPath); System.out.println(); System.out.println("get parent file"); File parentFile = file.getParentFile(); System.out.println("File Name: " + parentFile.getName()); } else System.out.println("File Doesn't Exist!"); } } Result File Name: test.txt Parent Path: C:\test get parent file File Name: test
delete() Method
delete() method 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.
Note: files deleted by the delete() method wouldn't go to the trash/recycle bin. Use moveToTrash() method in Desktop class to move a file to trash/recycle bin.
import java.io.File; public class SampleClass{ public static void main(String[] args){ File file = new File("C:\\test\\test.txt"); if(file.exists()){ String name = file.getName(); if(file.delete()) System.out.println(name + " is successfully deleted!"); else System.out.println(name + " couldn't be deleted!"); } else System.out.println("File Doesn't Exist!"); } }To delete directory with files, you must loop through the directory and delete all the files in the directory then, you can delete the directory.
renameTo() Method
renameTo() method renames the file denoted by this abstract pathname. Many aspects of the behavior of this method are inherently platform-dependent: The rename operation might not be able to move a file from one filesystem to another, it might not be atomic, and it might not succeed if a file with the destination abstract pathname already exists. The return value should always be checked to make sure that the rename operation was successful.
import java.io.File; public class SampleClass{ public static void main(String[] args){ File file = new File("C:\\test\\test.txt"); File replacement = new File("C:\\test\\renameTest.txt"); if(file.exists()){ String name = file.getName(); if(file.renameTo(replacement)) System.out.println(name + " is successfully renamed!"); else System.out.println(name + " couldn't be renamed!"); } else System.out.println("File Doesn't Exist!"); } }
list() and listFiles() Methods
list() method returns an array of String of names of files and directories in a directory whereas listFiles() returns an array of File of names of files and directories in a directory. list() and listFiles() has other forms but for the sake of simplicity, we're just gonna discuss list() and listFiles().
import java.io.File; public class SampleClass{ public static void main(String[] args){ File file = new File("C:\\test"); if(file.exists()){ String name = file.getName(); if(file.isDirectory()){ System.out.println(name + " is a directory!\n"); //list() method String[] names = file.list(); System.out.println("List Names"); for(String fileName : names) System.out.println(fileName); System.out.println(); System.out.println("List Files"); File[] files = file.listFiles(); for(File f : files){ String fileType = f.isFile() ? "is a file." : "is a directory."; System.out.println(f.getName() + " " + fileType); } } else System.out.println(name + " is not a directory!"); } else System.out.println("File Doesn't Exist!"); } } Result(Yours may be different) List Names read.txt renameTest.txt write.txt List Files read.txt is a file. renameTest.txt is a file. write.txt is a file.
mkdir() and mkdirs() Methods
mkdir creates a directory and returns true if the operation is successful. mkdirs() creates a directory and other necessary but nonexistent parent directories along the way. return true if the operation is successful. otherwise, returns. Note that if this operation fails it may have succeeded in creating some of the necessary parent directories.
import java.io.File; public class SampleClass{ public static void main(String[] args){ File file = new File("C:\\test\\folder1\\folder2"); if(!file.exists()){ //if folder1 is not existing then mkdir() will fail if(file.mkdir()){ System.out.println(file.getName() + " is created using mkdir()!"); } else{ System.out.println(file.getName() + " is not created using mkdir()!"); //mkdirs() will create folder1 then followed by folder2 if(file.mkdirs()) System.out.println(file.getName() + " is created using mkdirs()!"); else System.out.println(file.getName() + " is not created using mkdirs()!"); } } else System.out.println(file.getName() + " already exists!"); } }
toPath() Method
This method converts abstract pathname to a Path type that is associated with the default FileSystem.
import java.io.File; import java.nio.file.Path; public class SampleClass{ public static void main(String[] args){ File file = new File("C:\\test\\test.txt"); if(file.exists()){ Path path = file.toPath(); System.out.println("Name elements of path: " + path.toString()); for(int i = 0; i < path.getNameCount(); i++) System.out.println(path.getName(i)); } else System.out.println("File Doesn't Exist!"); } }
Path Interface
Path interface stores a path of a file. This interface is similar to the The File class. Path interface is used for the features available in java.nio.file package that require a Path interface, whereas File class is used for general-purpose file path storage.
To wrap a file path into a Path object. We can wrap the file path in a File object first then convert the File object to Path object by using toPath() method. Second is to use the get() method in Paths class.
import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; public class SampleClass{ public static void main(String[] args){ File file = new File("C:\\test\\test.txt"); if(file.exists()){ //First method //convert File object with pathname to Path object Path path = file.toPath(); //Second method: use the Paths.get() method in the //Paths class //Path path = Paths.get(file.toString()); //We can use name elements of a path as arguments //in Paths.get() //Path path = Paths.get("C:","test","test.txt"); System.out.println("Name elements of path: " + path.toString()); for(int i = 0; i < path.getNameCount(); i++) System.out.println(path.getName(i)); } else System.out.println("File Doesn't Exist!"); } }
getFileName() and getName() Methods
getFileName() method returns the file name of a file wrapped in Path object. getName() method returns a name element of a path denoted by an index.
import java.io.File; import java.nio.file.Path; public class SampleClass{ public static void main(String[] args){ File file = new File("C:\\test\\test.txt"); if(file.exists()){ //First method //convert File object with pathname into Path object Path path = file.toPath(); System.out.println(path.getName(0)); Path path2 = path.getFileName(); System.out.println(path2.getName(0)); } else System.out.println("File Doesn't Exist!"); } } Result test test.txt
normalize() Method
normalize() method removes the symbols "." and ".." and redundant name elements in a path. The precise definition of this method is implementation dependent but in general it derives from this path, a path that does not contain redundant name elements. In many file systems, the "." and ".." are special names used to indicate the current directory and parent directory.
import java.io.File; import java.nio.file.Path; public class SampleClass{ public static void main(String[] args){ //"..\\test" is redundant File file = new File("C:\\test\\..\\test\\test.txt"); //there's ".." File file2 = new File("C:\\test\\..\\test.txt"); File file3 = new File("C:\\test\\..\\test2\\test\\test.txt"); //convert File object with pathname into Path object Path path = file.toPath(); Path path2 = file2.toPath(); Path path3 = file3.toPath(); System.out.println(path.normalize()); System.out.println(path2.normalize()); System.out.println(path3.normalize()); } } Result C:\test\test.txt C:\test.txt C:\test2\test\test.txt
resolve() Method
resolve() method resolves this path against the given path. This method has a parameter that could be a Path or String type. If the given path is an absolute path then, this method will return the given path as a result. If the given path is empty then, it returns this path. If the given path is not absolute then, this path is considered as a directory and it's resolved against the given path.
import java.nio.file.Path; import java.nio.file.Paths; public class SampleClass{ public static void main(String[] args){ Path path = Paths.get("C:\\test"); Path otherPath = Paths.get("C:\\test2"); //"this" path is in the "path" variable. //given path is the path in the argument System.out.println(path.resolve(otherPath)); otherPath = Paths.get(""); System.out.println(path.resolve(otherPath)); otherPath = Paths.get("test2\\test2.txt"); System.out.println(path.resolve(otherPath)); } } Result C:\test2 C:\test C:\test\test2\test2.txt
resolveSibling() Method
resolveSibling() method resolves the given path against this path's parent path. This has similarities with resolve() method.
import java.nio.file.Path; import java.nio.file.Paths; public class SampleClass{ public static void main(String[] args){ Path path = Paths.get("C:\\test\\test.txt"); Path otherPath = Paths.get("myTest.txt"); System.out.println(path.toString()); //"this" path is in the "path" variable. //given path is the path in the argument System.out.println(path.resolveSibling(otherPath)); } } Result C:\test\test.txt C:\test\myTest.txt
relativize() Method
This method is the inverse of resolution like resolve(). This method attempts to construct a relative path that when resolved against this path, yields a path that locates the same file as the given path.This method creates a relative path when this path is resolved against the given path.
Both paths must have root components if one of them has one and the roots of both paths must be the same. A relative path cannot be constructed if only one of the paths have a root component. It can also be constructed if both paths don't have root component.
Where both paths have a root component then it is implementation dependent if a relative path can be constructed. If this path and the given path are equal then an empty path is returned.
import java.nio.file.Path; import java.nio.file.Paths; public class SampleClass{ public static void main(String[] args){ Path path = Paths.get("C:\\test\\test1.txt"); Path otherPath = Paths.get("C:\\myTest\\test2.txt"); //"this" path is in the "path" variable. //given path is the path in the argument Path relativePath = path.relativize(otherPath); System.out.println("relative: "+relativePath); System.out.println("resolve: "+path.resolve(relativePath)); path = Paths.get("C:\\test"); otherPath = Paths.get("C:\\test\\testcase\\myTest1.txt"); relativePath = path.relativize(otherPath); System.out.println("relative: "+relativePath); System.out.println("resolve: "+path.resolve(relativePath)); } } Result relative: ..\..\myTest\test2.txt resolve: C:\test\test1.txt\..\..\myTest\test2.txt relative: testcase\myTest1.txt resolve: C:\test\testcase\myTest1.txt
toFile() Method
This method converts Path type to File type. This method returns a File type that is the converted Path type.
import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; public class SampleClass{ public static void main(String[] args){ Path path = Paths.get("C:\\test"); File file = path.toFile(); System.out.println(file.getName()); } } Result test
Files Class
Files class is located at java.nio.file package. This class consists exclusively of static methods that operate on files, directories, or other types of files. We will discuss some methods in this class that may be useful for us.
Creating Symbolic Links
Symbolic links are special type of files that serve as links to files. Any operation done to a symbolic link will be done to the file that is link to that symbolic link, except for deleting and renaming. Deleting or renaming a symbolic link won't delete or rename the file that is linked to the symbolic link.
There are two types of symbolic links: soft link and hard link. Let's start with the soft link. To create a soft link we will use the Files.createSymbolicLink() method.
createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
The link parameter is the path of the symbolic link, target parameter is the path of the file that is going to be linked with the symbolic link and the attrs parameter is optional attributes to set atomically when creating the link.
Note: If you encounter a FileSystemException like this: java.nio.file.FileSystemException: c:\test\myLinks\testLink.txt:
A required privilege is not held by the client.
If you're using Windows, try running your cmd or IDE as administrator.
import java.io.IOException; import java.io.BufferedReader; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.Files; import java.lang.UnsupportedOperationException; public class SampleClass{ public static void main(String[] args){ Path target = Paths.get("C:\\test\\test.txt"); Path link = target.resolveSibling("myLinks\\testLink.txt"); try{ //we can omit the third argument since we //just want the default file attributes to //make this tutorial simple // //Note: soft link can be created even //the target file is not yet existing Files.createSymbolicLink(link, target); System.out.println("Soft link created!"); } catch(IOException e){ //Aside from failed or interrupted I/O operations, //IOException in this example is thrown //due to symbolic links incompatibility issues e.printStackTrace(); } catch(UnsupportedOperationException e){ //This exception will be thrown if //the file system that we're using which //is the default file system that is //provided by our OS doesn't support //symbolic links. Also, this exception //will be thrown if an operation is //not supported by the current //filesystem like file duplication e.printStackTrace(); } //once the symbolic link is created. We //can use it to indirectly access the //linked file try(BufferedReader reader = Files.newBufferedReader(link)){ String value = reader.readLine(); while(value != null){ System.out.println(value); value = reader.readLine(); } } catch(IOException e){ e.printStackTrace(); } } }After you successfully created the soft link. You will get this file
Note: Some operating system invalidates symbolic links when they're moved to a different root. For example, symbolic links from C: drive will be invalidated if they are moved to F: drive. If symbolic links are invalidated they become empty directories if the symbolic links are directories. Otherwise, they become empty files.
Next, let's create a hard link. Hard link is similar to soft link but more restrictive. These are the restrictions of hard link according to this article
- The target of the link must exist.
- Hard links are generally not allowed on directories.
- Hard links are not allowed to cross partitions or volumes. Therefore, they cannot exist across file systems.
- A hard link looks, and behaves, like a regular file, so they can be hard to find.
- A hard link is, for all intents and purposes, the same entity as the original file. They have the same file permissions, time stamps, and so on. All attributes are identical.
createLink(Path link, Path existing)
The existing parameter is the existing target file and the link parameter is the hard link.
Note: If you encounter a FileSystemException like this: java.nio.file.FileSystemException: c:\test\myLinks\testLink.txt:
A required privilege is not held by the client.
If you're using Windows, try running your cmd or IDE as administrator.
import java.io.IOException; import java.io.BufferedReader; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.Files; import java.lang.UnsupportedOperationException; public class SampleClass{ public static void main(String[] args){ Path target = Paths.get("C:\\test\\test.txt"); Path link = target.resolveSibling("myLinks\\hardLink.txt"); try{ Files.createLink(link, target); System.out.println("Hard link created!"); } catch(IOException e){ //Aside from failed or interrupted I/O operations, //IOException in this example is thrown //due to symbolic links incompatibility issues e.printStackTrace(); } catch(UnsupportedOperationException e){ //This exception will be thrown if //the file system that we're using which //is the default file system that is //provided by our OS doesn't support //symbolic links. Also, this exception //will be thrown if an operation is //not supported by the current //filesystem like file duplication e.printStackTrace(); } //once the symbolic link is created. We //can use it to indirectly access the //linked file try(BufferedReader reader = Files.newBufferedReader(link)){ String value = reader.readLine(); while(value != null){ System.out.println(value); value = reader.readLine(); } } catch(IOException e){ e.printStackTrace(); } } }After you successfully created the hard link. You will get this file
If we want to get the path of the linked file in a symbolic link, we can use the readSymbolicLink() method.
import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.Files; import java.lang.UnsupportedOperationException; public class SampleClass{ public static void main(String[] args) throws IOException{ Path target = Paths.get("C:\\test\\test.txt"); Path link = target.resolveSibling("myLinks\\testLink.txt"); try{ Files.createSymbolicLink(link, target); System.out.println("Soft link created!"); } catch(UnsupportedOperationException e){ e.printStackTrace(); } System.out.println("Linked File Path: " + Files.readSymbolicLink(link)); } }Some methods in the nio package follow symbolic links by default like toRealPath(LinkOption... options), exists(Path path, LinkOption... options) and others. Although, we can make them not follow symbolic links by adding LinkOption.NOFOLLOW_LINKS in their
options
parameter.
Some methods doesn't follow symbolic link by default like
walkFileTree(Path start, FileVisitor<? super Path> visitor)
Although, this method has second form which can enable following of symbolic links
walkFileTree(Path start, Set<FileVisitOption< options, int maxDepth, FileVisitor<? super Path< visitor)
In the
options
parameter we can put FileVisitOption.FOLLOW_LINKS to enable following of symbolic links when this method is used.
What do you mean following symbolic links? you might ask. When a method follows a symbolic link, it will access the file that is linked to that symbolic link. For example,
toRealPath()
returns the real path of the file linked to the symbolic link instead of the real path of the symbolic link itself.
When a method doesn't follow a symbolic link, it will access the symbolic link and not the linked file in the symbolic link.
Note: Beware of circular reference. Circular reference is a scenario where the target of a link points back to the original link. This often happens when linking directories. For example, myDir is a directory which is linked to dirA symbolic link, which is linked to dir2 symbolic link and dir2 has subdirectory dir3 which is a symbolic link pointing to myDir.
Circular references can cause havoc when a program is recursively walking a directory structure. However, this scenario has been accounted for and will not cause your program to loop infinitely.
copy() Method
This method copies a file to a target file. This method has three forms but we're gonna focus on one form:
copy(Path source, Path target, CopyOption... options)
source parameter is the file source, target parameter is the destination and options parameter is a number of options provided by StandardCopyOption and LinkOption. CopyOption is a superinterface of both classes.
You may include any of these options in this method:
REPLACE_EXISTING
COPY_ATTRIBUTES
NOFOLLOW_LINKS
This example demonstrates
copy()
method.
import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Files; import java.nio.file.StandardCopyOption; public class SampleClass{ public static void main(String[] args) throws IOException{ File source = new File("C:\\test\\test.txt"); File target = new File("C:\\test\\myTest\\test.txt"); if(!target.exists()){ Files.copy(source.toPath(), target.toPath()); System.out.println("Copy Completed!"); } else System.out.println(target.getName() + " already exists!"); } }In the example above,
copy()
is used without any CopyOption options. In this invocation, the copy fails(throws exceptions) if the target file already exists or is a symbolic link, except if the source and target are the same file where isSameFile(Path path, Path path2) returns true, in which case the method completes without copying the file.
If we use COPY_ATTRIBUTES but the target file already exists, Files.copy() will throw FileAlreadyExistsException.
import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.nio.file.FileAlreadyExistsException; public class SampleClass{ public static void main(String[] args){ Path source = Paths.get("C:\\test\\test.txt"); Path target = Paths.get("C:\\test\\myTest\\test.txt"); try{ //COPY_ATTRIBUTES attempts to copy the source file //attributes Files.copy(source, target, StandardCopyOption.COPY_ATTRIBUTES); System.out.println("Copy Completed!"); } catch(FileAlreadyExistsException e){ System.out.println("Couldn't create file. " + "File already exists"); } catch(IOException e){ e.printStackTrace(); } } }If we want to overwrite a target file, we can use the REPLACE_EXISTING option.
import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.Files; import java.nio.file.StandardCopyOption; public class SampleClass{ public static void main(String[] args) throws IOException{ Path source = Paths.get("C:\\test\\test.txt"); Path target = Paths.get("C:\\test\\myTest\\test.txt"); Files.copy(source, target, StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING); System.out.println("Copy Completed!"); } }Note: to copy all files in a non-empty directory, we need to individually copy each of directory's files.
delete() and deleteIfExists() Methods
This methods delete a file. A directory must be empty to be deleted. Otherwise, DirectoryNotEmptyException will be thrown. An implementation may require to examine the file to determine if the file is a directory. Consequently, these methods may not be atomic with respect to other file system operations.
Note: files deleted by these methods wouldn't go to the trash/recycle bin. Use moveToTrash() method in Desktop class to move a file to trash/recycle bin.
import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.Files; public class SampleClass{ public static void main(String[] args) throws IOException{ Path path1 = Paths.get("C:\\test\\test.txt"); Path path2 = Paths.get("C:\\test\\test2.txt"); //This method simply deletes a file Files.delete(path1); //This method deletes a file and returns a //boolean value. Returns true if the file //is successfully deleted. Returns false //if the file didn't exist. if(Files.deleteIfExists(path2)){ System.out.println("File deleted!"); } else System.out.println("File doesn't exist!"); } }
move() Method
This method moves a file to a target file. failing if the target file exists except if the source and target are the same file, in which case this method has no effect. For a non-empty directory with standard files, moving may involve copying rather than moving directories and this can be done using the copy method in conjunction with the Files.walkFileTree utility method. Thus, Files/directories in the current directory will be moved to the new directory.
We may include these options in this method:
REPLACE_EXISTING
ATOMIC_MOVE
import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.Files; import java.nio.file.StandardCopyOption; public class SampleClass{ public static void main(String[] args){ try{ //in this code, source and target have the same //parent directory. In this case, the source will be //replaced by the target and test.txt name will be //changed to test2.txt Path source = Paths.get("C:\\test\\test.txt"); Path target = source.resolveSibling("test2.txt"); Files.move(source, target, StandardCopyOption.REPLACE_EXISTING); System.out.println("First move operation is a success!"); //In this code, source and target don't have the //same parent directory. Thus, testA.txt will simply move //to myTest directory, replace an existing testA.txt in //myTest directory and testA.txt name will be changed to //test.txt source = Paths.get("C:\\test\\testA.txt"); target = Paths.get("C:\\test\\myTest\\test.txt"); Files.move(source, target, StandardCopyOption.REPLACE_EXISTING); System.out.println("Second move operation is a success!"); } catch(Exception e){ e.printStackTrace(); } } }
walkFileTree() Method
This method traverses a file tree. This method has two forms but we're going to focus on this form:
walkFileTree(Path start, FileVisitor<? super Path> visitor)
start parameter is the starting directory and the visitor parameter is a FileVisitor type. We need to create our FileVisitor implementation to manage files in a file tree during the operation. In this tutorial, we're going to create a simple implementation of FileVisitor so, SimpleFileVisitor will suffice.
By default this method form doesn't follow symbolic links. The second form of this method has a parameter that can enable following of symbolic links:
walkFileTree(Path start, Set<FileVisitOption< options, int maxDepth, FileVisitor<? super Path< visitor)
The
options
parameter determines whether symbolic links should be followed when traversing file tree using this method.
The difference between FileVisitor and SimpleFileVisitor is that SimpleFileVisitor doesn't require all of its methods to be overriden whereas FileVisitor requires all of its methods to be overriden. We also need FileVisitResult 'cause methods of SimpleFileVisitor and FileVisitor require FileVisitResult as return type.
In this tutorial, we're going to do an attempt to delete a non-empty directory. To do that, we need to delete all the files in the directory first before deleting the directory.
import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.Files; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.FileVisitResult; public class SampleClass{ public static void main(String[] args) throws IOException{ Path path = Paths.get("C:\\test\\testfolder"); Files.walkFileTree(path, new MySimpleVisitor()); } } class MySimpleVisitor extends SimpleFileVisitor<Path>{ @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); System.out.println(file.toString() + " file is deleted."); return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException { //if e is null it means that the traversing operation //is running fine if(e == null){ Files.delete(dir); System.out.println(dir.toString() + " directory "+ "is deleted."); } else throw e; return FileVisitResult.CONTINUE; } }In the example above, everytime walkFileTree() visits a file, one of the overriden methods in MySimpleVisitor will be called depending on the state of the operation. visitFile() is invoked for a file in a directory. postVisitDirectory() is invoked for a directory after entries in the directory, and all of their descendants, have been visited.
There are two methods that are not overriden here but they can be overriden: preVisitDirectory() and visitFileFailed(). Read the FileVisitor documentation for more details.
No comments:
Post a Comment