- [Tim] So in the last video,
we ended up talking about the file class
and some of the limitations.
So in this video,
we're gonna talk about how java.nio solves these problems
and also how it splits the functionality
that was in the file class
into several classes and interfaces.
Now, the java.nio.file class contains methods
for pointing to files
and also for performing file operations like delete.
Now in java.nio, the path interface sticks to file paths.
So file operations have been moved
to the java.nio.file.files class.
Now we saw this class in an earlier video
when we used it to read text files,
but now we're gonna actually look at it
at a little bit more detail.
So the files class contains methods that perform
a file system operation such as copy, move, delete, etc.
Now all its methods are static
so you don't need an instance of the class
to call its methods.
So we're gonna start off by looking at how we can check
whether a file or directory exists
which you may wanna do before you attempt other operations
on that particular file or directory.
Now it is important to understand that the path interface
doesn't actually know anything about the file system.
It merely understands paths.
So in a previous video, we got an exception
when we deliberately didn't pass enough information
to build a path to the subdirectory file.text
and if you recall, we saw that the exception didn't occur
when we created the path,
but rather when we tried to create the BufferedReader.
So what this demonstrates is that you can successfully
create paths to files that don't actually exist.
So to confirm that, let's actually give that a go.
So we're gonna create a path to a file that doesn't exist
so I'm gonna start typing Path path3 equals
FileSystems.getDefault.getPath
and we're gonna put a file that clearly doesn't exist
so thisfiledoesntexist.txt
and clearly that doesn't exist over here
because we're gonna be using the IntelliJ project by default
and then we're going to print out a message there
path3.toAbsolutePath.
All right, so we'll just run this and see what happens.
So we can see here we got the output
so happily it's printing out
the absolute path to a file that doesn't exist.
Now the java.nio.file class operates the same way
by the way,
until you actually try to access a file with a path,
and file is actually abstract.
Now in our application,
the rubber only really meets the road
when we try to create a BufferedReader using the path
and that's why the exception is thrown at that point.
Only then does it matter
if the file pointed to by the path actually exists.
Now of course if you're creating a file,
then it doesn't matter if it does exist,
but to create a file with a directory you specify
has to exist.
To confirm that, let's actually try the following code.
So I'm gonna type in Path path4 equals Paths.get
and we're gonna enter a path that we know doesn't exist
so on my Mac I'm going to put a fictitious path
Volumes/Test/ING,
something clearly that doesn't exist.
And if we wanted to
we could add in a second part of that path, abcdf,
and we'll finish with a filename whatever.txt.
Now if you're on a PC,
you might wanna do something instead like
%://, abddf and whatever.txt.
Basically you wanna specify a series of parameters
to make sure that we're pointing to a path
that doesn't exist.
All right, once we do that, we're going to just output it
so output path4.toAbsolutePath again.
And obviously we're not doing anything different
to the previous example other than specify the path
so we should just get it
quite happily printing out that path
as you can see it's doing down here.
So in other words, no exceptions are thrown.
Now because of this, depending on what you wanna do,
it can well be a good idea
to check for the existence of a file or directory
before you try to use it.
Now let's check to see
that the files directory actually exists.
So I can do that by typing filePath equals
FileSytems.getDefault.getPath
and we're gonna type in files
and we know here that files is the subfolder
that we created in a previous video
and let's actually see whether it exists.
We're gonna print out Exists = + File.exists(filePath).
We're gonna actually run that
and you can see we've got Exists = true there
so it's telling us that that folder
or that directory rather,
the files directory or the subdirectory does actually exist.
So let's actually check our bogus folder here,
either one of those.
We'll actually select the second one.
We'll actually select the file there,
but it could be a folder
and we can do print out Exists = + Files.exists(path4).
So if we try that, we should get a false
because that path, whatever we've chosen there,
shouldn't exist.
We made sure earlier that it doesn't exist.
And we get Exists = false there which is what we expect.
Now this exists method has an overloaded method
that accepts a second parameter
that specifies how you wanna handle symbolic links.
So you can choose to follow them or not follow them.
By default though, they're followed.
And if they're unfollowed,
then if the path contains the symbolic link
that points to an existing file,
the method will return false.
And there's also a files.notExist method
which returns true when the file or directory pointed to
by the path doesn't exist.
Now in a real world application,
you could check for the path's permission
in the print file method
and throw an exception if the file doesn't exist
or perhaps just let the IO exception be thrown
when you try to create the BufferedReader.
Now even if a file exists of course,
your application may not have permission to use it,
but you can actually check that
by using the files.isReadable method,
the files.isWritable method,
and the files.isExecutable method.
All right, so let's move on now on how to copy a file.
So we've set up a folder previously that contains that file.
Now let's actually create another folder now
that's got a few other directories
and the folder structure that we're trying to create
should look something like this.
All right, so this is the folder structure
that I'm about to create.
You can see we've got an example subfolder Dir1, Dir2,
and we've got a Dir3 here.
We've got various files in each one of those structures.
So that's the folder structure
we're going to try and create.
You'll see me creating that when we go back to IntelliJ.
All right, so let's go ahead
and we'll start by creating that new directory.
I'm gonna call that Examples with a capital E.
Then within the Examples folder,
we wanna create two directories
so it's going to be Dir1
and also Dir2.
Then in the Dir2 folder,
we're going to have a Dir3 folder like so
and then we need some files in each one of those folders.
So I'm just gonna take a copy of that
and paste it into the first folder,
but I'm actually change the name and call it file1.txt.
Then we'll take a copy of that
and that file also needs to exist
in the Dir2 and Dir3 folders
so Dir2 I'm gonna paste it into there, same filename,
and also the Dir3,
paste it in there.
And we also want that file to appear
in the top level Examples folder
so I'm gonna paste it in there.
All right, so we've got file.txt in the Examples folder,
in the Dir1, in the Dir2, as well as the Dir3
and let's take a copy of the file1
and we're gonna call this one file2.txt
and we're gonna copy that into the Dir3 folder
as well as the Dir2.
Okay, so I'll paste it into Dir2 and Dir3.
All right, so there's our folder structure.
We've got Examples.
We've got file1.txt in the Examples folder.
We've got a Dir1 folder that contains file1 and file2.txt.
The Dir2 folder contains file1, file2, and file3
which we haven't had a three yet but we'll do that shortly
and then the Dir3 subfolder contains file1 and file2.
So let's just take a copy of this and paste that
and we'll call that file3.txt and then we'll be good to go.
And again, the contents really don't matter of the file.
It's more the directory structure
and the fact that there are files there.
So let's close off some of these files that I've opened.
Okay.
So we've basically now built up a file tree
and a few files that we can work with.
So let's start off by running some code
to copy examples.file1, this one here,
in the Examples folder,
to copy that to Examples, file1copy.txt,
and what we're going to do is comment out
some of this code that we no longer need
so I'm just going to just comment all that out.
And I'm also gonna comment out the print file method
'cause we no longer need that.
And we'll just add another curly brace there
to make the code valid
and we're gonna start by typing path sourceFile,
we need to accept that import,
that's equal to FileSytems.getDefault.getPath
and we're gonna use Examples as the subfolder name
then the file, file1.txt.
So make sure you get your capitalization correct there
and that you're using exactly the same case
as you used for your folder names and your filenames
so that's the source file we wanna copy from.
Then the copyFile is equal to FileSystems.getDefault.getPath
and it's gonna be Examples,
I'm gonna call this file1copy.txt.
And then we just wanna do
a Files.copy(sourceFile, copyFile)
and what we need to do is wrap this with a try catch
so I'm going to do that so try,
let's move the code into there,
and we'll catch an IO exception
and we'll print a stack trace if we get an error.
So let's just try running that to see that it does work
and we should see that the file1copy.txt gets created
and you can see we get this file1copy.txt file
that was created from the copy.
All right, so let's finish the video here.
In the next video, we'll continue on.
We'll start looking at how to move a file,
how to rename a file,
how to delete a file, so on and so forth.
So I'll see you in the next video.