Lesson 14 - Working with files and folders in Java
In the previous lesson, Exceptions in Java for the third time and more techniques, we finished exceptions. Today we're going
to describe Java classes that don't depend on the file type in any way, so they
are for general use. They allow us to work with files and folders at the
operating system level, which we'll certainly need in our applications. In this
lesson we'll introduce the
File class, its methods and uses.
Absolute vs. relative path
Before we describe the
File class, let's talk briefly about the
absolute and relative path. Just to make these terms clear.
This is a path that starts with the root element of the filesystem. In the
case of Windows it'll be something like:
for Linux it'll be just
/. The absolute path does not need any
additional information to specify the location of the file. Everything is in one
place. But the problem is that the path is platform dependent. As we've already
mentioned, it differs for Windows and Linux. Therefore, I recommend not to use
absolute paths. Or just for program settings files.
The relative path does not start with the root of the filesystem. Instead,
it's determined based on an existing location (most often the current program's
folder), such as
images/. This is definitely the way to go when
working with files in the program.
The File class
File class has been in Java since the first release. Over
time, it turned out that it had some "issues" which resulted in releasing a new
API (but we'll talk about this in the next lesson).
The class represents either a file or folder. We need to create a new instance to work with the file/folder. This can be done very simply:
File file = new File("file.txt");
The constructor has 4 overloads:
public File(String pathname); public File(String parent, String child); public File(File parent, String child) public File(URI uri)
In the first case, both absolute and relative paths can be passed. If we use a relative path, the result is always determined from the file used.
The file used is the resulting JAR file, not *.class.
The second overload receives two strings. The first string represents the path to the parent and can be either relative or absolute. The second parameter is the path relative to the parent in the first parameter. A parent is any parent folder, such as "C://". A child is a file/folder that is located in the parent folder, for example: "C://file.txt"
The third overload is the same as the first, but it differs in the first
parameter, which is now another instance of the
The last overload accepts an URI. It stands for Uniform Resource Identifier. (Do not confuse with URL). The complete URI syntax is shown below:
URI is a document identification standard using the scheme described below. URL is a "subset" of URI and contains information on how to handle resources from a location.
This is the general scheme. But all we need is a basic one, where we replace 'scheme' with 'file' and then provide the path:
We'll most often encounter this approach when using various
images, sounds and other files that we pack in the JAR. We usually access these
files using the
getClass().getResource(String name) method. This
method returns the URI we pass to the
But we'll work with the first overload of the constructor most of the time.
The File class methods
The methods can be categorized into several categories:
We have the following get methods available, which we'll all try:
getAbsolutePath(): String- Returns the absolute path to the file
getCanonicalPath(): String- Returns the canonized file path
getFreeSpace(): long- Returns the number of free bytes in the partition where the file is located
getName(): String- returns the file name
getParent(): String- returns the absolute path to the parent, or
nullif the file itself is the parent
getParentFile(): File- Returns an instance of the
Fileclass representing the parent of the current file
getPath(): String- returns the path to the file (since we don't know in which format we get it, it's better to use
getTotalSpace(): long- returns the total number of bytes in the partition where the file is located
getUsableSpace(): long- Returns the number of used bytes for the current virtual machine; the result is more accurate than from the
We'll make a few examples just to be sure. We'll create one instance of the
File class and call all the GET methods on it.
For demonstration, I intentionally created an awkward directory structure to see the differences between the methods. Let's create the following folders:
src |---social | |---ict | |---filesfolders | |---App.java |---folders | |---file.txt
We'll create a
File class instance like this:
File file = new File("../../../files/file.txt");
We purposely used the
../ sequence several times
which takes us one folder up relatively to the current folder. This will make
the result more interesting.
Let's see the output of the individual methods:
Console application getAbsolutePath(): /tmp/ict/files-folders/../../../files/file.txt getCanonicalPath(): /files/file.txt getFreeSpace(): 0 getName(): file.txt getParent(): ../../../files getParentFile(): ../../../files getPath(): ../../../files/file.txt getTotalSpace(): 0 getUsableSpace(): 0
Set methods, as the name suggests, set some properties to the files. These are:
setExecutable(boolean executable, boolean ownerOnly): boolean- sets whether the file is executable; the second parameter is optional (there's an overload where this parameter is set to
trueautomatically); if the second parameter is
true, then the executability is set for the current user only
setLastModified(long time): boolean- sets the date when the file has been lastly modified
setReadable(boolean readable, boolean ownerOnly): boolean- sets whether the file can be read; the second parameter works the same as with the first method
setReadOnly(): boolean- a one-way method to set a file as read-only -> it won't be possible to write it anymore
setWritable(boolean writable, boolean ownerOnly): boolean- sets whether it's possible to write to the file; the second parameter works the same as with the first method
The Can methods are the following:
canExecute(): boolean- Returns
trueif the file can be executed,
canRead(): boolean- return
trueif the file is readable,
Using the "IS" methods we can ask the following questions:
isAbsolute(): boolean- Returns
trueif the instance was created using an absolute path
isDirectory(): boolean- Returns
trueif it's a folder
isFile(): boolean- Returns
trueif it's a file
isHidden(): boolean- Returns
trueif the file is hidden
We're now missing only the "functional" that do something with the file itself and which we'll use most often.
toURI(): URI- Creates a URI from the file instance used
createNewFile(): boolean- creates a new file if it doesn't exist; returns
trueif the file was created,
delete(): boolean- deletes the file; returns
trueif the file was deleted,
deleteOnExit(): void- deletes the file only after the program has finished
exists(): boolean- returns
trueif the file exists,
length(): long- returns the file size in bytes
list(): String - returns an array of absolute paths of the files in the folder
listFiles(): File - Returns an array of file instances in the folder
mkdir(): boolean- attempts to create the folder; returns
trueif the folder was created,
mkdirs(): boolean- attempts to create all folders in the path; returns
trueif all the folders have been created,
renameTo(File dest): boolean- renames the file to a new name; can be understood as "moving" a file from one location to another; this method is platform dependent; cannot be used to move the file between two file systems
toPath(): Path- creates a new
Pathinstance, which we'll discuss in the next lesson
The File API problems
File API suffers from the following problems:
- the vast majority of methods return only
falseif something goes wrong; the problem is that we don't know the cause of the failure
- renaming a file does not work the same on all platforms
- The API does not support symbolic links
- The API is missing metadata support (permissions, file owner, ...)
In the next lesson, Working with files and folders in Java - New API, we'll introduce new classes for working with files and folders that solve these problems.
No one has commented yet - be the first!