Want this course?
Course: JVM Fundamentals for Clojure
In this lesson we look at
java.io.File and how the
clojure.java.io namespace makes it easy to use.
A lot of times we're gonna want to read and write files in Java, or enclosure on the JVM and there is a system in Java, on the JVM, for representing file names. So, you could use a string. Most of the time, a string is just fine, but a very often you want to build up that path programmatically. Or, you want to query the file itself on the disk, to exist or a directory, that kind of thing, when you were modified. So, there is a system, it's part of java.io. It's in here. It's called file, I'm gonna, let's do Frames, we can use the Java Docs this way. Java.IO. And we're gonna look up File.
Okay. This class represents a path on your hard drive. So, directories, files, doesn't mean the file exists. Just 'cause you have this object, does not mean this file exists. Maybe you have the file and the file object and you're gonna create the file on disk using this. It's really just, like, the path. It's like having a URL. Doesn't mean that anything is there when you try to access it. It's just a string, same with the file. Now, file has a a few constructors. It has one that's just a string, it's just the path name.
That one is, you know, what do you expect? You have a string, you want to convert it into a file. So, if, you know, slashes and stuff are gonna get read in and parsed. Now, if you want to build something programmatically, sometimes you have a file, like a directory, you have a file and a representative path in a directory, and you have the name of a file in that directory, okay, this is getting a little high level. So like, let's see. I have this, def directory, and I have java.io.file, I'm gonna make a new one and it's the temp directory. Okay, doesn't mean it exists on the disk, it doesn't even mean it's a directory, it's just a path. Then I'm gonna do def temp-file, well, why don't I call this temp directory. Temp-file is gonna be java.io.file. Make a new one, this is the parent directory and then the file name is xyz. Okay, so now if I look at this file, we see that, well, that's just the program printing out temp-file. There. The path inside there has the whole thing. The tmp and xyz, the parent and the child. Okay, so that's easy, it's a way to build it out. Most things take strings too, but they're gonna be using file inside, and we'll see why. If you go down, that's how you construct it.
Oh, finally, there's one other way to construct it, it's with the URI, an object for URI which we'll see when we talk about networking in Java. If it is a file colon URI, then you can convert it into a file, otherwise it's gonna throw an exception. So if I have something like this: def uri is gonna be java.net.URI file://tmp/xyz.txt, that's a valid URL, and sometimes that's what you get. You know, that's how you represent a file name on your system using URI. Now, if I want to convert it to a file, I would do java.io.file pass it that URI. Oh, and this is not working. Why not? URI has an authority component, let me see. URI, what does that look like? Huh. Why couldn't I print it out here? I'll do it here. Java.io.file uri. Nope, didn't work. Hm. Very, oh right. It needs a third slash. My fault. There.
Okay, so yeah, file URIs. They have to start with a slash because that's the beginning of the file system. The double slash is syntax for the URL. Okay, sorry about that. So if I do this one, now we see it turns it into a file with the expected path, but if we did it with something else, java.net.URI This one is not gonna work, it's throwing exceptions, right. It's not a SEAM file. Okay, so you can convert, but, not all URLs are gonna work that way. We'll talk about URIs, like I said, in the JAVA Networking lesson.
Okay, so there's a bunch of stuff on files because obviously, you really don't want to operate on files query like how long is it, when was it created, can I read it, is it writable, all those kinds of things, are the things you wanna do. I'm not gonna go through all of them, but most things that you wanna do on files are in here. The interesting thing to me is the navigation. So like, if you have a directory, you can do a list, and you get an array of file names in there. You can do less files and you get actually an array of files. You know, stuff like that you can navigate, you can get the parent of the current file, get names, very important.
Now, this is the name of that file, like without the whole path, just the name of the file. You can get absolute path, which is the whole thing. You know, you can delete it. If you need to create a temporary file, this is a static method, this is actually really useful. This is a file that is guaranteed to be deleted when the JBM shuts down and I use this a lot. You need to give it a prefix and a suffix.
They can be any kind of string, but that's just to uniquely identify it. It's also gonna create this random string, like you can make as many as you want of them. And it will put it somewhere, but it's gonna delete it when the JBM goes down, which is nice. Alright, so now just to complete this thing, clojure.java.io the clojure namespace that wraps this java.io gives you a nice a nice wrapper for file, and it's just that file, and it has the three constructors. So, I could do /tmp/xyz.txt and this will work like that.
This is the equivalent to the java java new java.io.file. Like that. There's one that takes multiple, so you can do /tmp xyz.txt, gives you the same thing, Okay. This one doesn't have such an equivalent in Java, which lies pretty convenient. You're gonna have to do java.io.file and basically it turns into this nested thing. There's actually three nestings in here, so new java.io.file new java.io.file, so / is the first one, and then tmp and then xyz.txt. So who says that closure turns things insides out? This is exactly the inside out one. Isn't it? Cool. And you can also do it with the URI, so java.net.uri Let's just grab this one so I don't have to type it. Right. It just calls through to the constructor.