Want this course?
Dealing with temporary files
Course: JVM Fundamentals for Clojure
Creating temporary files on the JVM is not hard, per se, but it is not obvious, either. It's done with a very Java-esque style. In this lesson, we go through how to create a temporary file and how to create a temporary directory.
Right, we are talking about temporary files. This is one of those little practical details that is kind of a pain on the jvm. There is a solution but it's a little complex. So... What do I mean by temporary files? I'm talking about if you want to create a file just to write some data out and you don't really care what it's called but you wanna make sure that it gets cleaned up and that it's not gonna be in the home directory or the current directory. You want it somewhere out of the way. But you still need to write the disk or something.
So this kind of thing happens all the time and you think it should be really convenient and easy to do but it turns out that it's a little difficult. And I've had to figure it out several times. So I want to help you out with that. There are actually two different things that you have to do. So if we wanna create a temp file, create-temp-file. This is actually different from creating a temp directory. Create-temp-file is surprising very easy.
Okay so, one thing you might want to do is say use the directory /tmp, which is often there. But it might not always there if you're on a Windows directory they might not have /tmp. So there is a way to get this temp directory from the jvm running. And notice that this one has very interesting temp directory. Okay so you can rely on this property much more than you can rely on this /tmp being there.
I happen to know that I do have a /tmp. But this one I wanna use instead. So that's a string, so we're gonna wanna turn it into a file. So there. No I have a java.io.file with that file name in it. And I can put that up here. Def temp directory. And you know, it might give you a new temp directory every time you run this java run the jvm. Okay create temp file. I wanna create a temp file in that directory. Oh I'm gonna need to import something. Import a java class called java.io File. And there's another lesson on this file stuff.
So we call the function, the method createTempFile. We give it the prefix. So let's say temporary. We give it the suffix. So what's it's gonna do is it's gonna take the prefix and the suffix and in the middle, it's gonna generate some random number, some random characters and make a file name out of that. It's gonna sandwich it all together. You have the prefix, the random number, and then the suffix. So the suffix, say I wanna a text file, .txt. And then where do you want it? I want it in the temp directory.
Okay, now I can call it create-temp-file. And there, we have, it returns a file. So you get a handle on it. And it's going to be in this temp directory that we found from the property. And then notice the name of the file. It's got temporary which is from here. And it's got a bunch of numbers just to make sure it doesn't have any collision. And it's got the .txt. And let's see if it exists. .exists. Oh, I have to make a new one, tmp-file. Oops. True. So it not only does it create new the file name but it's there on the disk. And we can actually go and see in this tmp and open bar, oh god bar folders. Qt, yeah, t temporary, you see I have a bunch of temporary things there that I've created while I was testing this stuff out.
Okay, so let's get rid of these top level things. Alright, that's creating a temporary file. Not so bad. Not so bad. Now creating a temp directory is a little harder. Okay because there is no File/createTemp directory. In more recent versions of java, they have added some other classes that will do this. Here is the classes that we're gonna need. Java.nio.file File. And java.nio.file.attributes, attribute? FileAttribute, yeah. I hope, I think. It might be attributes. Did I misspell it? It's not compiling for me. Oh sorry. This is not File, it's Files. There. Okay. So with these two things we can do it. So there is... a nice, convenient function called on files. Notice it's different from File. CreateTempDirectory. And this takes three arguments. Two or three but we'll do the three one first.
So we're going to have the same temp directory except we need to convert it to what's called a path which is another weird java thing where it's got a difference between a file and a path. Even though they semantically mean the same thing, they are different things. Okay now the prefix. And now we need an empty array of FileAttributes. Why, because this is actually using one of those newer java language features that let's you have multiple arguments. And it collects them up into an array. And the compiler will do that and construct the array for you. But from closure, when we're calling a method like that, we actually have to build the array ourselves. It kinda sucks but you need to build a zero element array to pass this.
Okay toPath doesn't work. Oh, did I misspell it? There, okay. I just had to recompile. Alright now let's try this out. Create-temp-directory. And you see, it's returning a path. Okay so this is this new java stuff that I didn't start learning, I didn't learn, when I was learning java, cuz it didn't exist. And now that this stuff is there, I get confused with this. But this is a path, it's a Unix path because we're on a Unix system. And you notice, it created this directory here using our prefix. And again some random numbers. Okay but we don't wanna a path, we want a file. So just like we converted this file into a path with toPath, we're gonna convert the path to a file with toFile, oops, toFile.
Okay now when I run this, boom, this time we're getting a file. And we have a temporary directory. Okay so that is not that bad. I only had to import a few classes and call different things on it to coerce things into the right type. Another thing you can do is not pass it in the temp directory. And this will put it in the default temp directory anyway.
So if you wanna choose, you know I could say that toPath (io/file "/tmp". I can put something in tmp. And you notice what happen, it put it in tmp. Right, so this let's me choose, maybe I wanna pass it in here. Parent. And I can put it here. Parent. You know you have the choice now. So that's it. Just creating temporary files.