Quantcast
Channel: Scratch Where It's Itching
Viewing all articles
Browse latest Browse all 73

Thou Shall Close Thy Streams

$
0
0
You should always close your IO streams. Said like this, it sounds obvious. But in the light of some new Java 8 features, it took me some time to get around it.

I needed to write a small method for modifying a CSV file, basically change the last 1 of each line into a 0. Not really difficult. I would create a temporary file where I'll copy the original lines with the needed modification, then overwrite the original file with the one I created. Since I could use Java 8, I thought I would use a stream and lambdas. The code looked like this:

try (PrintWriter writer = new PrintWriter(Files.newBufferedWriter(tempFile))) {
	Files.lines(toConvert))
		.map(line -> line.replace(";1", ";0"))
		.forEach(line -> writer.println(line));
} 

Files.move(tempFile, toConvert, StandardCopyOption.ATOMIC_MOVE,
	StandardCopyOption.REPLACE_EXISTING);

Looks nice, except I had this weird java.nio.file.FileSystemException with the message "The process cannot access the file because it is being used by another process.". I was pretty sure that the only process using my file was my small program. So the problem was that the Files.lines() does not close the file. I found other references on the net to comfort my idea. So yes, I know, you can find it in the javadocs, and yes, the stream is autocloseable. So the way to go is the following:

try (Stream<String> reader = Files.lines(toConvert)) {
	reader.map(line -> line.replace(";1", ";0"))
		.forEach(line -> writer.println(line));
}

But to my defense, I'm not the only one having problems with the javadocs: https://bugs.openjdk.java.net/browse/JDK-8073923


Viewing all articles
Browse latest Browse all 73

Trending Articles