File to byte[] in Java
Asked Answered
D

26

929

How do I convert a java.io.File to a byte[]?

Dionysius answered 13/5, 2009 at 16:30 Comment(2)
One use that I can think of is reading serialized objects from file.Ordinarily
Another is to find the file type using the header.Lorri
P
580

It depends on what best means for you. Productivity wise, don't reinvent the wheel and use Apache Commons. Which is here FileUtils.readFileToByteArray(File input).

Potter answered 13/5, 2009 at 16:48 Comment(10)
@ymajoros: So true! I'd rather have some extra lines of code than yet another dependency. Dependencies have hidden costs. You need to stay up to date with that library, include the dependency in your build scripting etc, communicate it to people using your code etc etc. If you are already using a library that has code for it than use that, otherwsie I would say write it yourself.Intisar
This answers the question of how to read a file, but not the question of how to convert an object of type java.IO.File to byte[].Overtrade
How is this used to read a File to byte[]? I'm using Java6 so I can't use the NIO methods :(Iand
@ymajoros would you kindly share any "standard 3-lines solution" with us, so we don't have to rely on a reinventing-the-wheel-dependency?Mistake
@matteo: any? See other answers, e.g. Files.readAllBytes(). Simple, no dependency.Roseliaroselin
@Roseliaroselin that's not JDK 6Mastoidectomy
"Productivity wise, don't reinvent the wheel"- Efficiency-wise, if you are distributing an app (as opposed to being server based), don't include a massive library and all it's dependencies to avoid writing several lines of simple code.Lessee
Does this run the risk of reading in the bytes as modified UTF-8, or otherwise altering them as read? Validating (Decoding) bytes read through this fashion returns some errors with UTF-8 decoding whereas @Michael Pollmeier's method does not. Thoughts?Whitfield
Note this quote from the API docs on Files.readAllBytes(): "Note that this method is intended for simple cases where it is convenient to read all bytes into a byte array. It is not intended for reading in large files."Veratridine
mvnrepository.com/artifact/commons-io/commons-io/2.5Grant
E
1502

From JDK 7 you can use Files.readAllBytes(Path).

Example:

import java.io.File;
import java.nio.file.Files;

File file;
// ...(file is initialised)...
byte[] fileContent = Files.readAllBytes(file.toPath());
Edea answered 13/5, 2009 at 16:30 Comment(8)
@aldo.roman.nurena JDK7 introduced a File.toPath() method that will give you a Path Object.Falkner
You can get a Path from a File. Try: File file = new File("/path"); Path path = Paths.get(file.getAbsolutePath()); byte[] data = Files.readAllBytes(path);Sperrylite
only works on JRE 1.7, which requires Android KitKatMachinery
How is the file closing handled in java.nio - in other words, should the above code close something?Schnitzler
@Schnitzler See the link in the answer: "The method ensures that the file is closed..."Copalite
Useless on Android because of thisSandy
This now works on Android if targeting SDK version 26 and higher.Strath
In android its require API level 26 or up.Automata
P
580

It depends on what best means for you. Productivity wise, don't reinvent the wheel and use Apache Commons. Which is here FileUtils.readFileToByteArray(File input).

Potter answered 13/5, 2009 at 16:48 Comment(10)
@ymajoros: So true! I'd rather have some extra lines of code than yet another dependency. Dependencies have hidden costs. You need to stay up to date with that library, include the dependency in your build scripting etc, communicate it to people using your code etc etc. If you are already using a library that has code for it than use that, otherwsie I would say write it yourself.Intisar
This answers the question of how to read a file, but not the question of how to convert an object of type java.IO.File to byte[].Overtrade
How is this used to read a File to byte[]? I'm using Java6 so I can't use the NIO methods :(Iand
@ymajoros would you kindly share any "standard 3-lines solution" with us, so we don't have to rely on a reinventing-the-wheel-dependency?Mistake
@matteo: any? See other answers, e.g. Files.readAllBytes(). Simple, no dependency.Roseliaroselin
@Roseliaroselin that's not JDK 6Mastoidectomy
"Productivity wise, don't reinvent the wheel"- Efficiency-wise, if you are distributing an app (as opposed to being server based), don't include a massive library and all it's dependencies to avoid writing several lines of simple code.Lessee
Does this run the risk of reading in the bytes as modified UTF-8, or otherwise altering them as read? Validating (Decoding) bytes read through this fashion returns some errors with UTF-8 decoding whereas @Michael Pollmeier's method does not. Thoughts?Whitfield
Note this quote from the API docs on Files.readAllBytes(): "Note that this method is intended for simple cases where it is convenient to read all bytes into a byte array. It is not intended for reading in large files."Veratridine
mvnrepository.com/artifact/commons-io/commons-io/2.5Grant
I
322

Since JDK 7 - one liner:

byte[] array = Files.readAllBytes(Paths.get("/path/to/file"));

No external dependencies needed.

Intercept answered 2/7, 2015 at 13:47 Comment(5)
This is now a better choice than the accepted answer, which requires Apache Commons.Brannen
Thanks :) I also needed this one: String text = new String(Files.readAllBytes(new File("/path/to/file").toPath())); which is originally from https://mcmap.net/q/54229/-what-is-simplest-way-to-read-a-file-into-string-duplicateCanner
In Android, it requires min API level to be 26.Antagonistic
You'll need to add import java.nio.file.Files; and import java.nio.file.Paths; if you haven't already.Kammerer
this is useful for java8 as wellMidi
C
172
import java.io.RandomAccessFile;
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);

Documentation for Java 8: http://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html

Coir answered 8/12, 2011 at 13:57 Comment(6)
You have to check return value of f.read(). Here can sometimes happen, that you will not read whole file.Catnip
Such situation can occur only if file is changing while you are reading it. In all other cases IOException is thrown. To address this problem I suggest to open file in read-write mode: RandomAccessFile(fileName, "rw")Coir
I could imagine other sources for only reading a portion of the file (File is on a network share ...) readFully() has the contract you're searching for.Salcido
Remember that RandomAccessFile is not thread safe. So, synchronization may be needed in some cases.Dorolisa
@DmitryMitskevich There are other cases as well, on filesystems that are possibly non-conformat. e.g. reading "files" in /proc/ on linux can cause short reads (i.e. you need a loop to read it all)Lawsuit
This answer also appears to be faster than nio or streams for files of around 5m.Homogenetic
L
85

Basically you have to read it in memory. Open the file, allocate the array, and read the contents from the file into the array.

The simplest way is something similar to this:

public byte[] read(File file) throws IOException, FileTooBigException {
    if (file.length() > MAX_FILE_SIZE) {
        throw new FileTooBigException(file);
    }
    ByteArrayOutputStream ous = null;
    InputStream ios = null;
    try {
        byte[] buffer = new byte[4096];
        ous = new ByteArrayOutputStream();
        ios = new FileInputStream(file);
        int read = 0;
        while ((read = ios.read(buffer)) != -1) {
            ous.write(buffer, 0, read);
        }
    }finally {
        try {
            if (ous != null)
                ous.close();
        } catch (IOException e) {
        }

        try {
            if (ios != null)
                ios.close();
        } catch (IOException e) {
        }
    }
    return ous.toByteArray();
}

This has some unnecessary copying of the file content (actually the data is copied three times: from file to buffer, from buffer to ByteArrayOutputStream, from ByteArrayOutputStream to the actual resulting array).

You also need to make sure you read in memory only files up to a certain size (this is usually application dependent) :-).

You also need to treat the IOException outside the function.

Another way is this:

public byte[] read(File file) throws IOException, FileTooBigException {
    if (file.length() > MAX_FILE_SIZE) {
        throw new FileTooBigException(file);
    }

    byte[] buffer = new byte[(int) file.length()];
    InputStream ios = null;
    try {
        ios = new FileInputStream(file);
        if (ios.read(buffer) == -1) {
            throw new IOException(
                    "EOF reached while trying to read the whole file");
        }
    } finally {
        try {
            if (ios != null)
                ios.close();
        } catch (IOException e) {
        }
    }
    return buffer;
}

This has no unnecessary copying.

FileTooBigException is a custom application exception. The MAX_FILE_SIZE constant is an application parameters.

For big files you should probably think a stream processing algorithm or use memory mapping (see java.nio).

Latterll answered 13/5, 2009 at 16:30 Comment(5)
ios needs to be declared outside the tryRodin
The statement "ios.read(buffer)" in the second example will only read in the first 4096 bytes of the file (assuming same 4k buffer as used in first example). For the second example to work, I think the read has to be inside a while loop that checks the result for -1 (end of file reached).Intisar
Sorry, dismiss my remark above, missed the statement setting buffer to length of file. Still, I like the first example way more. Reading a whole file into a buffer in one go is not scalable. You will risk sunning out of memory when the file is large.Intisar
The "simplest" way would make use of try-with-resources.Maladapted
Cool, but a little to verbose.Caduceus
D
79

As someone said, Apache Commons File Utils might have what you are looking for

public static byte[] readFileToByteArray(File file) throws IOException

Example use (Program.java):

import org.apache.commons.io.FileUtils;
public class Program {
    public static void main(String[] args) throws IOException {
        File file = new File(args[0]);  // assume args[0] is the path to file
        byte[] data = FileUtils.readFileToByteArray(file);
        ...
    }
}
Dealer answered 13/5, 2009 at 17:8 Comment(1)
On maven repositoryAndrow
L
28

If you don't have Java 8, and agree with me that including a massive library to avoid writing a few lines of code is a bad idea:

public static byte[] readBytes(InputStream inputStream) throws IOException {
    byte[] b = new byte[1024];
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    int c;
    while ((c = inputStream.read(b)) != -1) {
        os.write(b, 0, c);
    }
    return os.toByteArray();
}

Caller is responsible for closing the stream.

Lessee answered 6/7, 2016 at 23:6 Comment(1)
Thank you. This is what I needIndustry
R
26
// Returns the contents of the file in a byte array.
    public static byte[] getBytesFromFile(File file) throws IOException {        
        // 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) {
            // File is too large
            throw new IOException("File 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;

        InputStream is = new FileInputStream(file);
        try {
            while (offset < bytes.length
                   && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
                offset += numRead;
            }
        } finally {
            is.close();
        }

        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("Could not completely read file "+file.getName());
        }
        return bytes;
    }
Rosel answered 13/5, 2009 at 16:32 Comment(2)
Also, put numRead inside the loop. Declare variables in the smallest valid scope you can. Putting it outside the while loop is only necessary to enable that complicated "while" test; it would be better to do the test for EOF inside the loop (and throw an EOFException if it occurs).Poulard
throw new IOException("File is too large!"); what should we do when the file is too large? Is there also any example about it?Pterous
E
25

You can use the NIO api as well to do it. I could do this with this code as long as the total file size (in bytes) would fit in an int.

File f = new File("c:\\wscp.script");
FileInputStream fin = null;
FileChannel ch = null;
try {
    fin = new FileInputStream(f);
    ch = fin.getChannel();
    int size = (int) ch.size();
    MappedByteBuffer buf = ch.map(MapMode.READ_ONLY, 0, size);
    byte[] bytes = new byte[size];
    buf.get(bytes);

} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} finally {
    try {
        if (fin != null) {
            fin.close();
        }
        if (ch != null) {
            ch.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

I think its very fast since its using MappedByteBuffer.

Expansion answered 13/5, 2009 at 16:57 Comment(5)
there is absolutely no need to use memory mapping if you are only going to read the file once, and it will end up using twice as much memory as using a normal FileInputStream.Coetaneous
Unfortunately MappedByteBuffer isn't automatically released.Rupp
awesome, the new example includes printStackTrace, classic broken exception handling.Coetaneous
I agree.. Its the default stuff that eclipse puts in. I think I should rethrow the exception !Expansion
Ive been benchmarking nio in order to create a byte[] from a File. Other than using a direct buffer it does indeed take twice as much memory. Though it is faster for very large files ( about twice as fast as a buffered IO for 200M) it seems to lose out by a factor of 5 for files around 5M.Homogenetic
S
24

Simple way to do it:

File fff = new File("/path/to/file");
FileInputStream fileInputStream = new FileInputStream(fff);

// int byteLength = fff.length(); 

// In android the result of file.length() is long
long byteLength = fff.length(); // byte count of the file-content

byte[] filecontent = new byte[(int) byteLength];
fileInputStream.read(filecontent, 0, (int) byteLength);
Stonwin answered 23/2, 2017 at 13:19 Comment(2)
There are simpler ways, such as the one-liners that have already been mentioned.Caduceus
@Caduceus Simpler ways yes - but the one liners don't fit all situations. Such as Android.Inellineloquent
A
21

Simplest Way for reading bytes from file

import java.io.*;

class ReadBytesFromFile {
    public static void main(String args[]) throws Exception {
        // getBytes from anyWhere
        // I'm getting byte array from File
        File file = null;
        FileInputStream fileStream = new FileInputStream(file = new File("ByteArrayInputStreamClass.java"));

        // Instantiate array
        byte[] arr = new byte[(int) file.length()];

        // read All bytes of File stream
        fileStream.read(arr, 0, arr.length);

        for (int X : arr) {
            System.out.print((char) X);
        }
    }
}
Allinclusive answered 23/1, 2014 at 8:59 Comment(4)
I argue on being the "Simplest Way" :)Entoblast
Can you explain here ? Why do you have an argue ?Allinclusive
Nothing special, but you say simplest and i see more simple solutions -> in my opinion it is not the simplest. Maybe it was couple of years ago, but world is changing. I would not label my own solutions with such a statement. ;) If only you wrote "In my opinion the simplest is.." or "the most simple i found.." Don't wanna bother you, just thought nice to communicate this.Entoblast
@MuhammadSadiq: don't import anything .*, it's considered to be bad practice.Caduceus
H
17

This is one of the simplest way

 String pathFile = "/path/to/file";
 byte[] bytes = Files.readAllBytes(Paths.get(pathFile ));
Harrar answered 24/3, 2021 at 9:2 Comment(1)
This adds no additional context to, and is a duplicate of, https://mcmap.net/q/53388/-file-to-byte-in-java (which was created years before this answer).Narcotism
F
16

Guava has Files.toByteArray() to offer you. It has several advantages:

  1. It covers the corner case where files report a length of 0 but still have content
  2. It's highly optimized, you get a OutOfMemoryException if trying to read in a big file before even trying to load the file. (Through clever use of file.length())
  3. You don't have to reinvent the wheel.
Flournoy answered 17/4, 2013 at 15:12 Comment(0)
E
14
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;

File file = getYourFile();
Path path = file.toPath();
byte[] data = Files.readAllBytes(path);
Entoblast answered 2/9, 2016 at 15:55 Comment(1)
What JDK level is this?Abisia
J
13

Using the same approach as the community wiki answer, but cleaner and compiling out of the box (preferred approach if you don't want to import Apache Commons libs, e.g. on Android):

public static byte[] getFileBytes(File file) throws IOException {
    ByteArrayOutputStream ous = null;
    InputStream ios = null;
    try {
        byte[] buffer = new byte[4096];
        ous = new ByteArrayOutputStream();
        ios = new FileInputStream(file);
        int read = 0;
        while ((read = ios.read(buffer)) != -1)
            ous.write(buffer, 0, read);
    } finally {
        try {
            if (ous != null)
                ous.close();
        } catch (IOException e) {
            // swallow, since not that important
        }
        try {
            if (ios != null)
                ios.close();
        } catch (IOException e) {
            // swallow, since not that important
        }
    }
    return ous.toByteArray();
}
Jacey answered 24/2, 2012 at 13:0 Comment(0)
H
9

I belive this is the easiest way:

org.apache.commons.io.FileUtils.readFileToByteArray(file);
Harrison answered 3/4, 2014 at 12:4 Comment(1)
there is already an answer with this suggestion from Tom in 2009Chipmunk
Y
8

ReadFully Reads b.length bytes from this file into the byte array, starting at the current file pointer. This method reads repeatedly from the file until the requested number of bytes are read. This method blocks until the requested number of bytes are read, the end of the stream is detected, or an exception is thrown.

RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
Y answered 16/4, 2015 at 8:13 Comment(0)
A
6

If you want to read bytes into a pre-allocated byte buffer, this answer may help.

Your first guess would probably be to use InputStream read(byte[]). However, this method has a flaw that makes it unreasonably hard to use: there is no guarantee that the array will actually be completely filled, even if no EOF is encountered.

Instead, take a look at DataInputStream readFully(byte[]). This is a wrapper for input streams, and does not have the above mentioned issue. Additionally, this method throws when EOF is encountered. Much nicer.

Armlet answered 12/10, 2012 at 21:3 Comment(0)
R
5

Not only does the following way convert a java.io.File to a byte[], I also found it to be the fastest way to read in a file, when testing many different Java file reading methods against each other:

java.nio.file.Files.readAllBytes()

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;

public class ReadFile_Files_ReadAllBytes {
  public static void main(String [] pArgs) throws IOException {
    String fileName = "c:\\temp\\sample-10KB.txt";
    File file = new File(fileName);

    byte [] fileBytes = Files.readAllBytes(file.toPath());
    char singleChar;
    for(byte b : fileBytes) {
      singleChar = (char) b;
      System.out.print(singleChar);
    }
  }
}
Runic answered 9/4, 2018 at 13:38 Comment(0)
M
5
//The file that you wanna convert into byte[]
File file=new File("/storage/0CE2-EA3D/DCIM/Camera/VID_20190822_205931.mp4"); 

FileInputStream fileInputStream=new FileInputStream(file);
byte[] data=new byte[(int) file.length()];
BufferedInputStream bufferedInputStream=new BufferedInputStream(fileInputStream);
bufferedInputStream.read(data,0,data.length);

//Now the bytes of the file are contain in the "byte[] data"
Merritt answered 14/5, 2020 at 4:50 Comment(2)
While this code may provide a solution to the question, it's better to add context as to why/how it works. This can help future users learn, and apply that knowledge to their own code. You are also likely to have positive feedback from users in the form of upvotes, when the code is explained.Journalism
Well, that's the important part that i will keep in mind in future posts. Thanks for your useful insights.Merritt
B
4

Let me add another solution without using third-party libraries. It re-uses an exception handling pattern that was proposed by Scott (link). And I moved the ugly part into a separate message (I would hide in some FileUtils class ;) )

public void someMethod() {
    final byte[] buffer = read(new File("test.txt"));
}

private byte[] read(final File file) {
    if (file.isDirectory())
        throw new RuntimeException("Unsupported operation, file "
                + file.getAbsolutePath() + " is a directory");
    if (file.length() > Integer.MAX_VALUE)
        throw new RuntimeException("Unsupported operation, file "
                + file.getAbsolutePath() + " is too big");

    Throwable pending = null;
    FileInputStream in = null;
    final byte buffer[] = new byte[(int) file.length()];
    try {
        in = new FileInputStream(file);
        in.read(buffer);
    } catch (Exception e) {
        pending = new RuntimeException("Exception occured on reading file "
                + file.getAbsolutePath(), e);
    } finally {
        if (in != null) {
            try {
                in.close();
            } catch (Exception e) {
                if (pending == null) {
                    pending = new RuntimeException(
                        "Exception occured on closing file" 
                             + file.getAbsolutePath(), e);
                }
            }
        }
        if (pending != null) {
            throw new RuntimeException(pending);
        }
    }
    return buffer;
}
Benedetta answered 13/5, 2009 at 18:9 Comment(0)
S
4
public static byte[] readBytes(InputStream inputStream) throws IOException {
    byte[] buffer = new byte[32 * 1024];
    int bufferSize = 0;
    for (;;) {
        int read = inputStream.read(buffer, bufferSize, buffer.length - bufferSize);
        if (read == -1) {
            return Arrays.copyOf(buffer, bufferSize);
        }
        bufferSize += read;
        if (bufferSize == buffer.length) {
            buffer = Arrays.copyOf(buffer, bufferSize * 2);
        }
    }
}
Staw answered 12/11, 2012 at 11:33 Comment(0)
P
2

Another Way for reading bytes from file

Reader reader = null;
    try {
        reader = new FileReader(file);
        char buf[] = new char[8192];
        int len;
        StringBuilder s = new StringBuilder();
        while ((len = reader.read(buf)) >= 0) {
            s.append(buf, 0, len);
            byte[] byteArray = s.toString().getBytes();
        }
    } catch(FileNotFoundException ex) {
    } catch(IOException e) {
    }
    finally {
        if (reader != null) {
            reader.close();
        }
    }
Poseidon answered 25/11, 2014 at 10:24 Comment(1)
don't use hollow catch blocks. it makes debugging hard.Caduceus
J
2

Try this :

import sun.misc.IOUtils;
import java.io.IOException;

try {
    String path="";
    InputStream inputStream=new FileInputStream(path);
    byte[] data=IOUtils.readFully(inputStream,-1,false);
}
catch (IOException e) {
    System.out.println(e);
}
Jeffcott answered 4/2, 2019 at 15:20 Comment(3)
That requires a particular JRE implementation which will break the app if run on another JRE.Recipe
little mistake: is IOException and not IOexception, but thanks:)Centipoise
@MatanMarciano: my badCaduceus
A
1

Can be done as simple as this (Kotlin version)

val byteArray = File(path).inputStream().readBytes()

EDIT:

I've read docs of readBytes method. It says:

Reads this stream completely into a byte array. Note: It is the caller's responsibility to close this stream.

So to be able to close the stream, while keeping everything clean, use the following code:

val byteArray = File(path).inputStream().use { it.readBytes() }

Thanks to @user2768856 for pointing this out.

Alberik answered 31/8, 2020 at 12:31 Comment(1)
Use File(path).inputStream().use { it.readBytes() } it will close your stream.Fixing
F
1

try this if you have target version less than 26 API

 private static byte[] readFileToBytes(String filePath) {

    File file = new File(filePath);
    byte[] bytes = new byte[(int) file.length()];

    // funny, if can use Java 7, please uses Files.readAllBytes(path)
    try(FileInputStream fis = new FileInputStream(file)){
        fis.read(bytes);
        return bytes;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;

}
Furred answered 9/7, 2021 at 16:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.