读入的字节都写入字节数组中
嗨,大家好,Java程序员经常在现实世界中遇到编程问题,他们需要将文件中的数据加载到字节数组中,该文件可以是文本文件或二进制文件。 一个示例是将文件的内容转换为String以显示。 不幸的是,用于表示文件和目录的Java File类没有方法toByteArray()
。 它仅保存路径,并允许您执行某些操作(如打开和关闭文件),但不允许直接将File转换为字节数组 。 无论如何,无需担心,因为还有其他几种方法可以将File读入字节数组,您将在此Java文件教程中学习这些方法。
如果您喜欢Apache Commons和像我这样的Google Guava,那么您可能已经熟悉单行代码,该代码可以将文件快速读取到字节数组中。 如果不是,那么现在正是探索这些API的合适时机。
在本教程中,我们将看到7个不同的示例,将File读取为字节数组 ,其中一些使用第三方库,而另一些使用JDK 6和JDK 7核心Java库。
根据您的选择,可以使用以下任何一种方法将文件数据转换为字节。 要记住的一件事是您对字节数组的处理方式。 如果要从字节数组创建String ,请提防字符编码。 您可能需要通过读取元数据信息(例如HTML页面和XML文档的Content-Type)来找出正确的字符编码。
在读取XML文档时,首先读取XML文件并将其存储在String中是一个坏主意。 相反,最好将InputStream
传递给XML解析器,它们将自己正确地确定编码。
还有一点要注意的是,您不能将大于2GB的文件读取到一个字节数组中,为此您需要多个字节数组。 此限制来自Java中的数组索引为int类型,其最大值为2147483647
,大约等于2GB 。
顺便说一句,我希望您总体上熟悉基本的Java编程和Java API。
用Java将文件读入字节数组的7种方法
在不浪费您更多时间的情况下,以下是将文件加载到Java中的字节数组中的所有七种方法:
1)使用Apache Commons IOUtils
如果您不讨厌第三方库,这是将文件数据读取到字节数组中最简单的方法之一。 它之所以有用,是因为您不需要从头开始编写代码,也不必担心异常处理等。
byte [] filedata = IOUtils.toByteArray( new FileInputStream( "info.xml" [] filedata = IOUtils.toByteArray( "info.xml" ));
IOUtils.toByteArray(InputStream input)
获取以下内容:
InputStream作为byte [] 。 此方法还在内部缓冲输入,因此不需要使用BufferedInputStream
,但是它不是null安全的。 如果输入为null
,则抛出NullPointerException
。
2)使用Apache Commons FileUtils
org.apache.commons.io
包中的FileUtils class
提供了常规的文件操作功能,例如写入文件或从文件读取。 此方法用于将文件的内容读取到字节数组中,这的好处是文件始终处于关闭状态。
byte [] data = FileUtils.readFileToByteArray( new File( "info.xml" ));
3)使用FileInputStream和JDK
这是将文件内容读入字节数组的经典方法。 完成操作后,别忘了关闭流 。 这是使用Java中的FileInputStream类将文件读入字节数组的代码:
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; }
在生产中,使用finally块关闭流以释放文件描述符。
4)使用Google Guava Files类
Google Guava的Files类提供了用于处理文件的实用方法,例如将文件转换为字节数组,具有指定字符集的字符串,进行复制,移动等Files.toByteArray()
方法将文件中的所有字节读取为字节数组,然后如果文件大小大于可能的最大字节数组(2 ^ 31 – 1),则抛出IllegalArgumentException
。
byte [] bytes = Files.toByteArray( new File( "info.xml" [] bytes = Files.toByteArray( "info.xml" ));
这种将文件内容读入字节数组的方法具有多个优点,首先,您不需要重新发明轮子 。 其次,它使用NIO读取文件 ,其性能将比流IO更好。 您也不必像Guava那样担心处理异常和关闭流。
5)使用番石榴的ByteStreams实用程序
Guava的ByteStreams类提供了用于处理字节数组和I / O流的实用程序方法。 toByteArray()
使用InputStream并将所有字节读入字节数组,但它不会关闭流 ,因此您需要自己关闭它。
这是一个原因,我不喜欢这种方法,我们在上一节中看到的Java 7示例负责关闭流。
byte [] g2Bytes = ByteStreams.toByteArray( new FileInputStream( "info.xml" ));
顺便说一句,如果您正在使用Java内存约束环境,例如
Android ,然后考虑使用诸如proguard之类的混淆器从第三方库中删除未使用的类。 例如,默认情况下,番石榴会为APK添加2MB以上的内存。 但是使用Proguard时,它的大小约为250KB
6)使用JDK 7 NIO文件和路径
如果您使用的是Java 7,则这是将File转换为字节数组的最佳方法。 它允许您从文件读取所有字节并将其捕获到字节数组中。 您只需要知道文件的路径即可。
这是读取Java 7中文件的代码示例:
Path path = Paths.get( "info.xml" Path path = Paths.get( "info.xml" ); byte [] raw = java.nio.file.Files.readAllBytes(path);
这种方法的最大优点是它不需要任何第三方库 。 这也是一种静态方法,因此非常方便。 它还可以确保在读取所有字节或引发I / O错误或其他运行时异常时关闭文件。 从第一版开始就缺少Java。
顺便说一句,此方法仅打算用于方便将所有字节读入字节数组的情况下使用。 如果不能分配所需大小的数组(例如, 文件大于2GB) ,则不适合读取大文件并抛出OutOfMemoryError 。
顺便说一句,如果您只有File对象而不是Path,那么您也可以使用
File.toPath()
在JDK 1.7中将File转换为Path。
7)在Java中使用RandomAccessFile
您还可以使用RandomeAccessFile将File转换为字节数组,如下所示,尽管您也可以使用read(byte[])
方法,但最好使用readFully。
RandomAccessFile f = new RandomAccessFile( "info.xml" , "rw" ); byte [] b = new byte [( int )f.length()]; f.readFully(b);
另外,请注意, RandomAccessFile不是线程安全的。 因此,在某些情况下可能需要同步。
最后,这里的某些代码不是生产质量,因为它们无法正确处理异常。 在现实世界中,所有文件处理代码都必须在finally块中关闭流以释放与此相关的文件描述符,否则可能会导致java.io.IOException:打开文件太多错误 。
有时您会期望像Apache commons IO之类的库能够正确关闭流,如下面从的代码段所示
FileUtils
类阿帕奇百科全书IO,所述的closeQuietly()
方法关闭流忽略空值和异常。
InputStream in = null ;
try {
in = openInputStream(file);
return IOUtils.toByteArray(in, file.length());
} finally {
IOUtils.closeQuietly(in);
}
}
但这并不总是正确的,因为Google Guava的ByteStreams.toByteArray
方法不会关闭流。 最好在生产代码中使用特定方法之前检查文档。 通常,最好使用JDK API(如果可用),这就是为什么对JDK的充分了解对成为一名专业Java程序员有很大帮助。
Java程序,用Java将文件读入字节数组
这是我们完整的Java程序,用于将文件读入Java的字节数组中。 这结合了我上面显示的所有6种方法。 您可以复制粘贴此示例,然后在您喜欢的IDE(如Eclipse,NetBeans或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; /**
*
* @author Javin Paul
*/ 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" [] filedata = IOUtils.toByteArray( "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" [] bytes = Files.toByteArray( "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" )); "File to byte[] using Guvava \n " ));
// Example 6: Using JDK 7 NIO Path and Files class
Path path = Paths.get( "info.xml" 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: [] using IOUtils.toByteArray File to byte [] using IOUtils.toByteArray File to Name: Société Générale Headquarters: Île-de-France, France [] using FileUtils 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 array Using Google Convert File to byte array Using Google
Name: Société Générale Headquarters: Île-de-France, France [] using Guvava File to byte [] using Guvava
Name: Société Générale Headquarters: Île-de-France, France [] in JDK 7 [] in JDK Read File to byte [] in JDK
Name: Société Générale Headquarters: Île-de-France, France [] in Java using RandomAccessFile Load File to [] in Java using RandomAccessFile byte [] in Java using RandomAccessFile
Name: Société Générale Headquarters: Île-de-France, France
在7ways的本教程中,这就是用Java将文件读入字节数组的全部内容 。 现在,您知道有多种使用Java读取文件的方法,其中一种方法是使用第三方库,例如Apache Commons IO,Google Guava,Apache MINA,以及其他方法,仅使用标准JDK文件输入输出类。 根据您的要求,可以使用这些解决方案中的任何一种来将文件数据读取为Java中的字节。 如果要将字节数组转换为字符串,请注意字符编码。
另外,请记住,Java中的数组只能容纳有限数量的数据,因为其长度不能超过Integer.MAX_VALUE
(2GB)。 因此,尽管可以使用输入流读取大数据,但不能将大文件转换为单字节数组,但需要分块或使用多个字节数组处理它们。
如果您喜欢本文,并且想了解有关最新Java版本中改进的文件IO的更多信息,请查看以下教程:
- 完整的Java开发人员路线图( 指南 )
- Java 8中逐行读取文件的3种方法( 示例 )
- 2020年学习Java的10门课程( 课程 )
- 如何使用Java中的BufferedReader逐行读取文本文件? ( 回答 )
- Java程序员在2020年可以学习的15件事( 文章 )
- 如何在Java中使用内存映射文件? ( 回答 )
- 破解编码面试的5大技巧( 技能 )
- 如何在Java中将XML文件读取为String? ( 教程 )
- 如何使用Apache POI在Java中读取/写入Excel(XLS和XLSX)文件? ( 教程 )
- 在Java中解析CSV文件的2种方法? ( 回答 )
- 如何在Java中删除包含文件的目录? ( 回答 )
- 如何使用SAX解析器解析Java中的XML文件? ( 指南 )
- 如何在Java中将JSON转换为Object? ( 示例 )
- 如何使用JDOM解析器读取Java中的XML文件? ( 教程 )
- 如何使用Jackson Streaming API解析大型JSON文件? ( 示例 )
- 如何在Java 8中一行读取文件? ( 示例 )
- 如何用Java复制文件? ( 示例 )
- 如何在Java中为文件生成MD5校验和? ( 解决方案 )
- 如何在Java中读取/写入RandomAccessFile? ( 示例 )
感谢您到目前为止阅读本文。 如果您发现此Java文件教程很有用,请与您的朋友和同事分享。 如果您有任何疑问或反馈,请留言。
翻译自: https://www.javacodegeeks.com/2020/04/7-examples-to-read-file-into-a-byte-array-in-java.html
读入的字节都写入字节数组中