Java programmers often face scenarios in real-world programming, where they need to load data from a file into a byte array, it could be text or binary file. One example is to convert the contents of a file into String for display. Unfortunately, Java’s File class, which is used to represent both files and directories, doesn’t have a method say toByteArray(). It only holds path and allows you to perform certain operations like opening and closing file, but doesn’t allow you to directly convert File to a byte array. Anyway, no need to worry as there are several other ways to read File into a byte array and you will learn those in this Java file tutorial.
If you are a fan of Apache commons and Google Guava like me, then you may already familiar with one-liner code, which can quickly read a file into a byte array; if not, then this is the right time to explore those API.
In this tutorial, we are going to see 7 different examples to read File to a byte array, some by using third party libraries, and others by using JDK 6 and JDK 7 core Java libs.
Depending upon your choice, you can use any of the following methods to convert file data into bytes. One thing to keep in mind is what you are doing with byte array; if you are creating String from a byte array, then beware with character encoding. You may need to find out correct character encoding by reading metadata information like Content-Type of HTML pages and of XML documents.
While reading XML documents, it’s a bad idea to first read an XML file and store it in a String. Instead, it’s better to pass InputStream to XML parsers, and they will figure out the encoding themselves correctly.
One more thing to note is that you cannot read file larger than 2GB into a single byte array, you need multiple byte arrays for that. This limitation comes from the fact that the array index in Java is of int type, whose maximum value is 2147483647, roughly equivalent to 2GB.
Btw, I am expecting that you are familiar with basic Java Programing and Java API in general.
Without wasting any more of your time, here are all the seven ways to load a file into a byte array in Java:
This is one of the easiest ways to read a file data into a byte array, provided you don’t hate third-party libraries. It’s productive because you don’t need to code it from scratch, worrying about exception handling, etc.
byte[] filedata = IOUtils.toByteArray(new FileInputStream("info.xml"));
The IOUtils.toByteArray(InputStream input) Gets the contents of an InputStream as a byte[]. This method also buffers the input internally, so there is no need to use a BufferedInputStream, but it’s not null-safe. It throws NullPointerException if the input is null.
The FileUtils class from org.apache.commons.io package provides a general file manipulation facility like writing to a file or reading from a file. This method is used to read the contents of a file into a byte array, and the good thing about this is that the file is always closed.
byte[] data = FileUtils.readFileToByteArray(new File("info.xml"));
This is the classic way of reading the file’s content into a byte array. Don’t forget to close the stream once done. Here is the code to read a file into a byte array using FileInputStream class in Java:
public static byte[] readFile(String file) throws IOException {
File f = new File(file);
// work only for 2GB file, because array index can only up to Integer.MAX
byte[] buffer = new byte[(int)f.length()];
FileInputStream is = new FileInputStream(file);
is.read(buffer);
is.close();
return buffer;
}
In production, use finally block to close streams to release file descriptors.
Files class of Google Guava provides utility methods for working with files, like converting files to a byte array, to string with specified charset, copy, move, etc. Files.toByteArray() method reads all bytes from a file into a byte array and throws IllegalArgumentException if the file size is bigger than the largest possible byte array (2^31 – 1).
byte[] bytes = Files.toByteArray(new File("info.xml"));
This approach of reading files content into byte array has several advantages, first of all, you don’t need to reinvent the wheel. Second, it uses NIO for reading a file, which will perform better than stream IO. You also don’t need to worry about handling exceptions and closing streams, as Guava does for you.
Guava’s ByteStreams class provides utility methods for working with byte arrays and I/O streams. The toByteArray() takes an InputStream and reads all bytes into a byte array but it does not close the stream, so you need to close it by yourself.
This is one reason, I don’t prefer this method, the Java 7 example we saw in the last section takes care of closing streams.
byte[] g2Bytes = ByteStreams.toByteArray(new FileInputStream("info.xml"));
By the way, If you are using Java in-memory constraint environment like Android, then consider using obfuscator like proguard to remove unused classes from third-party libraries. For example, Guava by default adds more than 2MB to an APK. But with Proguard it comes down to about 250KB
If you are using Java 7, then this is the best way to convert File into a byte array. It allows you to read all bytes from a file and capture them in a byte array. All you need to know is the path of the file.
Here is the code sample to read a file in Java 7:
Path path = Paths.get("info.xml");
byte[] raw = java.nio.file.Files.readAllBytes(path);
The biggest advantage of this approach is that it doesn’t require any third-party libraries. It’s also a static method, which makes it very convenient. It also ensures that the file is closed when all bytes have been read or an I/O error, or other runtime exception, is thrown. Something Java has been lacking from the first edition.
By the way, this method is only intended for simple use where it is convenient to read all bytes into a byte array. It is not intended for reading large files and throws OutOfMemoryError, if an array of the required size cannot be allocated, for example, the file is larger than 2GB.
By the way, if you only have File object and not Path then you can also use File.toPath() to convert File to Path in JDK 1.7.
You can also use RandomeAccessFile to convert File into an array of bytes as shown below, though you can also use read(byte[]) method, it’s better to use readFully.
RandomAccessFile f = new RandomAccessFile("info.xml", "rw");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
Also, note that RandomAccessFile is not thread-safe. So, synchronization may be needed in some cases.
Last thing, some of the code here is not production quality, as they are not handling exceptions properly. In real-world, all file handling code must close streams in finally block to release file descriptor associated with that, failure to do so may result in you java.io.IOException: Too many open files error.
Sometimes you can expect libraries like Apache commons IO for closing streams properly, as seen below from a code snippet from FileUtils class of Apache Commons IO, the closeQuietly() methods close a stream ignoring nulls and exceptions.
InputStream in = null;
try {
in = openInputStream(file);
return IOUtils.toByteArray(in, file.length());
} finally {
IOUtils.closeQuietly(in);
}
}
In this tutorial, we are going to see 7 different examples to read File to a byte array, some by using third party libraries, and others by using JDK 6 and JDK 7 core Java libs.
Depending upon your choice, you can use any of the following methods to convert file data into bytes. One thing to keep in mind is what you are doing with byte array; if you are creating String from a byte array, then beware with character encoding. You may need to find out correct character encoding by reading metadata information like Content-Type of HTML pages and of XML documents.
While reading XML documents, it’s a bad idea to first read an XML file and store it in a String. Instead, it’s better to pass InputStream to XML parsers, and they will figure out the encoding themselves correctly.
One more thing to note is that you cannot read file larger than 2GB into a single byte array, you need multiple byte arrays for that. This limitation comes from the fact that the array index in Java is of int type, whose maximum value is 2147483647, roughly equivalent to 2GB.
Btw, I am expecting that you are familiar with basic Java Programing and Java API in general.
7 ways to read a file into a byte array in Java
Without wasting any more of your time, here are all the seven ways to load a file into a byte array in Java:
1) Using Apache Commons IOUtils
This is one of the easiest ways to read a file data into a byte array, provided you don’t hate third-party libraries. It’s productive because you don’t need to code it from scratch, worrying about exception handling, etc.
byte[] filedata = IOUtils.toByteArray(new FileInputStream("info.xml"));
The IOUtils.toByteArray(InputStream input) Gets the contents of an InputStream as a byte[]. This method also buffers the input internally, so there is no need to use a BufferedInputStream, but it’s not null-safe. It throws NullPointerException if the input is null.
2) Using Apache Commons FileUtils
The FileUtils class from org.apache.commons.io package provides a general file manipulation facility like writing to a file or reading from a file. This method is used to read the contents of a file into a byte array, and the good thing about this is that the file is always closed.
byte[] data = FileUtils.readFileToByteArray(new File("info.xml"));
3) Using FileInputStream and JDK
This is the classic way of reading the file’s content into a byte array. Don’t forget to close the stream once done. Here is the code to read a file into a byte array using FileInputStream class in Java:
public static byte[] readFile(String file) throws IOException {
File f = new File(file);
// work only for 2GB file, because array index can only up to Integer.MAX
byte[] buffer = new byte[(int)f.length()];
FileInputStream is = new FileInputStream(file);
is.read(buffer);
is.close();
return buffer;
}
In production, use finally block to close streams to release file descriptors.
4) Using Google Guava Files class
Files class of Google Guava provides utility methods for working with files, like converting files to a byte array, to string with specified charset, copy, move, etc. Files.toByteArray() method reads all bytes from a file into a byte array and throws IllegalArgumentException if the file size is bigger than the largest possible byte array (2^31 – 1).
byte[] bytes = Files.toByteArray(new File("info.xml"));
This approach of reading files content into byte array has several advantages, first of all, you don’t need to reinvent the wheel. Second, it uses NIO for reading a file, which will perform better than stream IO. You also don’t need to worry about handling exceptions and closing streams, as Guava does for you.
5) Using Guava’s ByteStreams utility
Guava’s ByteStreams class provides utility methods for working with byte arrays and I/O streams. The toByteArray() takes an InputStream and reads all bytes into a byte array but it does not close the stream, so you need to close it by yourself.
This is one reason, I don’t prefer this method, the Java 7 example we saw in the last section takes care of closing streams.
byte[] g2Bytes = ByteStreams.toByteArray(new FileInputStream("info.xml"));
By the way, If you are using Java in-memory constraint environment like Android, then consider using obfuscator like proguard to remove unused classes from third-party libraries. For example, Guava by default adds more than 2MB to an APK. But with Proguard it comes down to about 250KB
6) Using JDK 7 NIO Files and Path
If you are using Java 7, then this is the best way to convert File into a byte array. It allows you to read all bytes from a file and capture them in a byte array. All you need to know is the path of the file.
Here is the code sample to read a file in Java 7:
Path path = Paths.get("info.xml");
byte[] raw = java.nio.file.Files.readAllBytes(path);
The biggest advantage of this approach is that it doesn’t require any third-party libraries. It’s also a static method, which makes it very convenient. It also ensures that the file is closed when all bytes have been read or an I/O error, or other runtime exception, is thrown. Something Java has been lacking from the first edition.
By the way, this method is only intended for simple use where it is convenient to read all bytes into a byte array. It is not intended for reading large files and throws OutOfMemoryError, if an array of the required size cannot be allocated, for example, the file is larger than 2GB.
By the way, if you only have File object and not Path then you can also use File.toPath() to convert File to Path in JDK 1.7.
7) Using RandomAccessFile in Java
You can also use RandomeAccessFile to convert File into an array of bytes as shown below, though you can also use read(byte[]) method, it’s better to use readFully.
RandomAccessFile f = new RandomAccessFile("info.xml", "rw");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
Also, note that RandomAccessFile is not thread-safe. So, synchronization may be needed in some cases.
Last thing, some of the code here is not production quality, as they are not handling exceptions properly. In real-world, all file handling code must close streams in finally block to release file descriptor associated with that, failure to do so may result in you java.io.IOException: Too many open files error.
Sometimes you can expect libraries like Apache commons IO for closing streams properly, as seen below from a code snippet from FileUtils class of Apache Commons IO, the closeQuietly() methods close a stream ignoring nulls and exceptions.
InputStream in = null;
try {
in = openInputStream(file);
return IOUtils.toByteArray(in, file.length());
} finally {
IOUtils.closeQuietly(in);
}
}
but it’s not always true, as Google Guava’s ByteStreams.toByteArray method doesn’t close the stream. It’s better to check documentation before using a particular method in production code. In general, it’s better to use JDK API if available and that’s why a good knowledge of JDK goes a long way to becoming an expert Java programmer.
Java Program to Read A file into Byte Array in Java
Here is our complete Java program to read a file into a byte array in Java. This combines all the 6 approaches I have shown above. You can copy-paste this example and run in your favorite IDE like Eclipse, NetBeans, or IntelliJIDEA.
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
/**
*
*/
public class Testing {
public static void main(String args[]) throws IOException {
// Example 1: Using Apache Commons IOUtils to read file into byte array
byte[] filedata = IOUtils.toByteArray(new FileInputStream("info.xml"));
String str = new String(filedata, "UTF-8");
System.out.println("File to byte[] using IOUtils.toByteArray \n" + str);
// Example 2: Reading File to byte[] using FileUtils class
byte[] data = FileUtils.readFileToByteArray(new File("info.xml"));
System.out.println("Converting File to byte[] using FileUtils \n"
+ new String(data, StandardCharsets.UTF_8));
// Example 3: Using FileInputStream and JDK
byte[] contents = readFile("info.xml");
System.out.printf("File to byte[] Java without thirdpaty library %n %s %n",
new String(contents, StandardCharsets.UTF_8));
// Example 4: Using Google Guava, uses NIO
byte[] bytes = Files.toByteArray(new File("info.xml"));
System.out.printf("Convert File to byte array Using Google %n %s %n",
new String(bytes, "UTF-8"));
// Example 5:
byte[] g2Bytes = ByteStreams.toByteArray(new FileInputStream("info.xml"));
System.out.println("File to byte[] using Guvava \n " + new String(g2Bytes, "UTF-8"));
// Example 6: Using JDK 7 NIO Path and Files class
Path path = Paths.get("info.xml");
byte[] raw = java.nio.file.Files.readAllBytes(path);
System.out.println("Read File to byte[] in JDK 7 \n " + new String(raw, "UTF-8"));
//Example 7: Using RandomAccessFile in Java
RandomAccessFile f = new RandomAccessFile("info.xml", "rw");
byte[] b = new byte[(int) f.length()];
f.readFully(b);
System.out.println("Load File to byte[] in Java using RandomAccessFile \n "
+ new String(b, "UTF-8"));
}
/*
* Reading File into byte array using JDK classes only
*/
public static byte[] readFile(String file) throws IOException {
File f = new File(file);
// work only for 2GB file, because array index can only upto Integer.MAX
byte[] buffer = new byte[(int) f.length()];
FileInputStream is = new FileInputStream(file);
is.read(buffer);
is.close();
return buffer;
}
}
Output:
File to byte[] using IOUtils.toByteArray
Name: Société Générale
Headquarters: Île-de-France, France
Converting File to byte[] using FileUtils
Name: Société Générale
Headquarters: Île-de-France, France
File to byte[] Java without thirdpaty library
Name: Société Générale
Headquarters: Île-de-France, France
Convert File to byte array Using Google
Name: Société Générale
Headquarters: Île-de-France, France
File to byte[] using Guvava
Name: Société Générale
Headquarters: Île-de-France, France
Read File to byte[] in JDK 7
Name: Société Générale
Headquarters: Île-de-France, France
Load File to byte[] in Java using RandomAccessFile
Name: Société Générale
Headquarters: Île-de-France, France
That’s all on this tutorial of 7ways to read a file into a byte array in Java. Now you know that there are multiple ways to read the file in Java, some by using third party libraries like Apache Commons IO, Google Guava, Apache MINA, and others by just employing standard JDK file input-output classes. Depending upon your requirement, you can use any of these solutions to read file data into a byte in Java. Keep an eye on character encoding if you are converting byte array to String.
Also, remember that array in Java can only hold a limited amount of data as it’s length cannot exceed Integer.MAX_VALUE (2GB). So you cannot convert a large file into a single-byte array, though you can read large data using input stream, you need to process them in chunks or using multiple byte arrays.
Source: javacodegeeks.com
0 comments:
Post a Comment