Dante May Code
Dante May Code

Reputation: 11247

How to read bytes from a file, whereas the result byte[] is exactly as long

I want the result byte[] to be exactly as long as the file content. How to achieve that.

I am thinking of ArrayList<Byte>, but it doe not seem to be efficient.

Upvotes: 2

Views: 1268

Answers (4)

Joachim Sauer
Joachim Sauer

Reputation: 308001

Personally I'd go the Guava route:

File f = ...
byte[] content = Files.toByteArray(f);

Apache Commons IO has similar utility methods if you want.

If that's not what you want, it's not too hard to write that code yourself:

public static byte[] toByteArray(File f) throws IOException {
    if (f.length() > Integer.MAX_VALUE) {
        throw new IllegalArgumentException(f + " is too large!");
    }
    int length = (int) f.length();
    byte[] content = new byte[length];
    int off = 0;
    int read = 0;
    InputStream in = new FileInputStream(f);
    try {
        while (read != -1 && off < length) {
            read = in.read(content, off, (length - off));
            off += read;
        }
        if (off != length) {
            // file size has shrunken since check, handle appropriately
        } else if (in.read() != -1) {
            // file size has grown since check, handle appropriately
        }
        return content;
    } finally {
        in.close();
    }
}

Upvotes: 5

Stephan
Stephan

Reputation: 43013

Small function that you can use :


// Returns the contents of the file in a byte array.
public static byte[] getBytesFromFile(File file) throws IOException {
    InputStream is = new FileInputStream(file);

    // Get the size of the file
    long length = file.length();

    // You cannot create an array using a long type.
    // It needs to be an int type.
    // Before converting to an int type, check
    // to ensure that file is not larger than Integer.MAX_VALUE.
    if (length > Integer.MAX_VALUE) {
        throw new RuntimeException(file.getName() + " is too large");
    }

    // Create the byte array to hold the data
    byte[] bytes = new byte[(int)length];

    // Read in the bytes
    int offset = 0;
    int numRead = 0;
    while (offset < bytes.length
           && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
        offset += numRead;
    }

    // Ensure all the bytes have been read in
    if (offset < bytes.length) {
        throw new IOException("Could not completely read file "+file.getName());
    }

    // Close the input stream and return bytes
    is.close();
    return bytes;
}

Upvotes: 1

Nikita Rybak
Nikita Rybak

Reputation: 68006

I'm pretty sure File#length() doesn't iterate through the file. (Assuming this is what you meant by length()) Each OS provides efficient enough mechanisms to find file size without reading it all.

Upvotes: 4

Femaref
Femaref

Reputation: 61437

Allocate an adequate buffer (if necessary, resize it while reading) and keep track of how many bytes read. After finishing reading, create a new array with the exact length and copy the content of the reading buffer.

Upvotes: 2

Related Questions