2
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.