Writing byte[] to a File in Java – 在Java中写字节[]到文件

最后修改: 2020年 12月 15日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick tutorial, we’re going to learn several different ways to write a Java byte array to a file. We’ll start at the beginning, using the Java IO package. Next, we’ll look at an example using Java NIO. After that, we’ll use Google Guava and Apache Commons IO.

在这个快速教程中,我们将学习几种不同的方法,把一个Java字节数组写到文件中。我们将从头开始,使用Java IO包。接下来,我们将看一个使用Java NIO的例子。之后,我们将使用Google Guava和Apache Commons IO。

2. Java IO

2.Java IO

Java’s IO package has been around since JDK 1.0 and provides a collection of classes and interfaces for reading and writing data.

Java的IO包从JDK 1.0开始就存在了,它提供了一个用于读写数据的类和接口集合。

Let’s use a FileOutputStream to write the image to a file:

让我们使用一个FileOutputStream来把图像写到一个文件中。

File outputFile = tempFolder.newFile("outputFile.jpg");
try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
    outputStream.write(dataForWriting);
}

We open an output stream to our destination file, and then we can simply pass our byte[] dataForWriting to the write method. Note that we’re using a try-with-resources block here to ensure that we close the OutputStream in case an IOException is thrown.

我们为我们的目标文件打开一个输出流,然后我们可以简单地将我们的byte[] dataForWriting传递给write方法。请注意,我们在这里使用了一个try-with-resources,以确保我们关闭OutputStream,以防抛出IOException

3. Java NIO

3.Java NIO

The Java NIO package was introduced in Java 1.4, and the file system API for NIO was introduced as an extension in Java 7. Java NIO is uses buffering and is non-blocking, whereas Java IO uses blocking streams. The syntax for creating file resources is more succinct in the java.nio.file package.

Java NIO 包在 Java 1.4 中引入,NIO 的文件系统 API 在 Java 7 中作为扩展引入。Java NIO使用缓冲,并且是非阻塞的,而Java IO使用阻塞流。java.nio.file包中,创建文件资源的语法更加简洁。

We can write our byte[] in one line using the Files class:

我们可以使用Files类在一行中编写我们的byte[]

Files.write(outputFile.toPath(), dataForWriting);

Our example either creates a file or truncates an existing file and opens it for write. We can also use Paths.get(“path/to/file”) or Paths.get(“path”, “to”, “file”) to construct the Path that describes where our file will be stored. Path is the Java NIO native way of expressing paths.

我们的例子要么创建一个文件,要么截断一个现有的文件,并打开它进行写入。我们也可以使用Paths.get(“path/to/file”)Paths.get(“path”, “to”, “file”)来构造Path,描述我们的文件将被保存在哪里。Path是Java NIO表达路径的本地方式。

If we need to override the file opening behavior, we can also provide OpenOption to the write method.

如果我们需要覆盖文件的打开行为,我们也可以为OpenOptionwrite方法。

4. Google Guava

4.谷歌番石榴

Guava is a library by Google that provides a variety of types for performing common operations in Java, including IO.

Guava是Google提供的一个库,它为在Java中执行常见操作提供了各种类型,包括IO。

Let’s import Guava into our pom.xml file:

让我们把Guava导入到我们的pom.xml文件。

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.0.1-jre</version>
</dependency>

4.1. Guava Files

4.1.瓜娃文件

As with the Java NIO package, we can write our byte[] in one line:

与Java NIO包一样,我们可以在一行中编写我们的byte[]

Files.write(dataForWriting, outputFile);

Guava’s Files.write method also takes an optional OptionOptions and uses the same defaults as java.nio.Files.write.

Guava的Files.write方法也需要一个可选的OptionOptions并使用与java.nio.Files.write相同的默认值。

There’s a catch here though: The Guava Files.write method is marked with the @Beta annotation. According to the documentation, that means it can change at any time and so is not recommended for use in libraries.

但这里有一个问题。Guava的Files.write方法被标记为@Beta注释根据文档,这意味着它可以在任何时候改变,因此不建议在库中使用。

So, if we’re writing a library project, we should consider using a ByteSink.

因此,如果我们正在编写一个库项目,我们应该考虑使用ByteSink

4.2. ByteSink

4.2ByteSink

We can also create a ByteSink to write our byte[]:

我们还可以创建一个ByteSink来写入我们的byte[]

ByteSink byteSink = Files.asByteSink(outputFile);
byteSink.write(dataForWriting);

The ByteSink is a destination to which we can write bytes. It supplies an OutputStream to the destination.

ByteSink是一个我们可以写入字节的目的地。它向目的地提供一个OutputStream

If we need to use a java.nio.files.Path or to supply a special OpenOption, we can get our ByteSink using the MoreFiles class:

如果我们需要使用java.nio.files.Path或者提供一个特殊的OpenOption,我们可以使用MoreFiles类获得我们的ByteSink

ByteSink byteSink = MoreFiles.asByteSink(outputFile.toPath(), 
    StandardOpenOption.CREATE, 
    StandardOpenOption.WRITE);
byteSink.write(dataForWriting);

5. Apache Commons IO

5.Apache Commons IO

Apache Commons IO provides some common file tasks.

Apache Commons IO提供一些常见的文件任务。

Let’s import the latest version of commons-io:

让我们导入最新版本的commons-io

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>

Now, let’s write our byte[] using the FileUtils class:

现在,让我们使用FileUtils类编写我们的byte[]

FileUtils.writeByteArrayToFile(outputFile, dataForWriting);

The FileUtils.writeByteArrayToFile method is similar to the other methods that we’ve used in that we give it a File representing our desired destination and the binary data we’re writing. If our destination file or any of the parent directories don’t exist, they’ll be created.

FileUtils.writeByteArrayToFile方法与我们所使用的其他方法类似,我们给它一个File,代表我们想要的目的地和我们要写入的二进制数据。如果我们的目标文件或任何父目录不存在,它们将被创建。

6. Conclusion

6.结语

In this short tutorial, we learned how to write binary data from a byte[] to a file using plain Java and two popular Java utility libraries: Google Guava and Apache Commons IO.

在这个简短的教程中,我们学习了如何使用普通Java和两个流行的Java工具库将二进制数据从byte[]写到文件。Google Guava和Apache Commons IO。

As always, the example code is available over on GitHub.

像往常一样,示例代码可在GitHub上获得