\$\begingroup\$
\$\endgroup\$
0
I have these easy-to-use methods for reading and writing binary data in files.
FileTools.java:
package net.coderodde.file;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Objects;
/**
* This class contains utility methods for writing and reading binary data in
* files.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Feb 29, 2016)
*/
public class FileTools {
/**
* This method returns the byte array that represent the contents of
* {@code file}.
*
* @param file the file to read.
* @return the array of bytes representing the contents of the input file.
*/
public static byte[] readFile(File file)
throws IOException, FileNotFoundException {
Objects.requireNonNull(file, "The input file is null.");
long size = file.length();
checkSize(size);
byte[] data;
int bytesRead;
try (FileInputStream stream = new FileInputStream(file)) {
data = new byte[(int) size];
bytesRead = stream.read(data);
}
if (bytesRead != size) {
throw new IllegalStateException(
"File size and read count mismatch. File size: " +
size + ", bytes read: " + bytesRead);
}
return data;
}
/**
* Writes the byte array {@code data} to the file {@code file}. After
* successful operation of this method, the input file will contain exactly
* the contents of the input data.
*
* @param file the file to write to.
* @param data the data array to write.
* @throws java.io.IOException if file IO fails.
* @throws java.io.FileNotFoundException if file does not exist.
*/
public static void writeFile(File file, byte[] data)
throws IOException, FileNotFoundException {
Objects.requireNonNull(file, "The input file is null.");
Objects.requireNonNull(data, "The input data to write is null.");
try (BufferedOutputStream stream = new BufferedOutputStream(
new FileOutputStream(file))) {
stream.write(data);
}
}
// This method ensures that file size is small enough to be represented
// using a variable of type 'int'.
private static final void checkSize(long size) {
if (size > Integer.MAX_VALUE) {
throw new IllegalStateException(
"The target file is too large: " + size + " bytes. " +
"Maximum allowed size is " + Integer.MAX_VALUE +
"bytes.");
}
}
}
FileToolsTest.java:
package net.coderodde.file;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import org.junit.Test;
import static org.junit.Assert.*;
public class FileToolsTest {
private static final int ITERATIONS = 100;
private static final int MAXIMUM_DATA_LENGTH = 20_000;
@Test
public void test() {
long seed = System.nanoTime();
Random random = new Random(seed);
System.out.println("Seed = " + seed);
for (int i = 0; i < ITERATIONS; ++i) {
File file = new File("funky.txt");
byte[] data = new byte[random.nextInt(MAXIMUM_DATA_LENGTH)];
random.nextBytes(data);
try {
FileTools.writeFile(file, data);
byte[] result = FileTools.readFile(file);
assertTrue(Arrays.equals(result, data));
} catch (FileNotFoundException ex) {
fail(ex.getMessage());
} catch (IOException ex) {
fail(ex.getMessage());
}
file.delete();
}
}
}
Please, tell me anything that comes to mind.
asked Mar 1, 2016 at 6:16
1 Answer 1
\$\begingroup\$
\$\endgroup\$
From your "reinventing-the-wheel" tag, I assume you're already aware of Guava's and Apache Commons' utilities. So my only nitpick is that the int
cast might be clearer if it was closer to the size check:
long sizeLong = file.length();
checkSize(sizeLong);
int size = (int)sizeLong;
Or if you want to be a little more "clever":
int size = checkSize(file.length());
//...
private static final int checkSize(long size) {
//...
return (int)size;
}
lang-java