读取和写入二进制文件
使用流 I/O 读取文件
要打开一个文件进行读取,可以使用 newInputStream(Path, OpenOption...)
方法。此方法返回一个未缓冲的输入流,用于从文件中读取字节。
Path file = ...;
try (InputStream in = Files.newInputStream(file);
BufferedReader reader =
new BufferedReader(new InputStreamReader(in))) {
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException x) {
System.err.println(x);
}
使用流 I/O 创建和写入文件
可以使用 newOutputStream(Path, OpenOption...)
方法创建文件、追加到文件或写入文件。此方法打开或创建用于写入字节的文件,并返回一个未缓冲的输出流。
该方法接受一个可选的 OpenOption
参数。如果未指定任何打开选项,并且文件不存在,则创建一个新文件。如果文件存在,则将其截断。此选项等效于使用 CREATE
和 TRUNCATE_EXISTING
选项调用该方法。
以下示例打开一个日志文件。如果文件不存在,则创建它。如果文件存在,则打开它以进行追加。
import static java.nio.file.StandardOpenOption.*;
import java.nio.file.*;
import java.io.*;
public class LogFileTest {
public static void main(String[] args) {
// Convert the string to a
// byte array.
String s = "Hello World! ";
byte data[] = s.getBytes();
Path p = Paths.get("./logfile.txt");
try (OutputStream out = new BufferedOutputStream(
Files.newOutputStream(p, CREATE, APPEND))) {
out.write(data, 0, data.length);
} catch (IOException x) {
System.err.println(x);
}
}
}
使用通道 I/O 读取和写入文件
虽然流 I/O 每次读取一个字符,但通道 I/O 每次读取一个缓冲区。 ByteChannel
接口提供基本的读写功能。 SeekableByteChannel
是一个 ByteChannel
,它具有在通道中维护位置并更改该位置的能力。 SeekableByteChannel
还支持截断与通道关联的文件以及查询文件的大小。
能够移动到文件中的不同点,然后从该位置读取或写入,使得随机访问文件成为可能。有关更多信息,请参见随机访问文件部分。
有两种方法可以读取和写入通道 I/O。
newByteChannel(Path, OpenOption...)
newByteChannel(Path, Set<? extends OpenOption>, FileAttribute<?>...)
注意:
newByteChannel()
方法返回一个SeekableByteChannel
的实例。使用默认文件系统,您可以将此可搜索字节通道转换为FileChannel
,从而提供对更多高级功能的访问,例如将文件的一部分直接映射到内存中以实现更快的访问,锁定文件的一部分以防止其他进程访问它,或者从绝对位置读取和写入字节,而不会影响通道的当前位置。
两种 newByteChannel()
方法都允许您指定一个 OpenOption
选项列表。除了一个选项外, newOutputStream()
方法使用的相同打开选项都受支持: READ
是必需的,因为 SeekableByteChannel
支持读写。
指定 READ
将打开通道以进行读取。指定 WRITE
或 APPEND
将打开通道以进行写入。如果未指定这些选项中的任何一个,则通道将打开以进行读取。
以下代码片段读取文件并将其打印到标准输出
public static void readFile(Path path) throws IOException {
// Files.newByteChannel() defaults to StandardOpenOption.READ
try (SeekableByteChannel sbc = Files.newByteChannel(path)) {
final int BUFFER_CAPACITY = 10;
ByteBuffer buf = ByteBuffer.allocate(BUFFER_CAPACITY);
// Read the bytes with the proper encoding for this platform. If
// you skip this step, you might see foreign or illegible
// characters.
String encoding = System.getProperty("file.encoding");
while (sbc.read(buf) > 0) {
buf.flip();
System.out.print(Charset.forName(encoding).decode(buf));
buf.clear();
}
}
}
以下示例(为 UNIX 和其他 POSIX 文件系统编写)创建一个具有特定文件权限的日志文件。此代码创建一个日志文件,如果它已经存在,则追加到该日志文件。日志文件以所有者可读写、组只读的权限创建。
import static java.nio.file.StandardOpenOption.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.io.*;
import java.util.*;
public class LogFilePermissionsTest {
public static void main(String[] args) {
// Create the set of options for appending to the file.
Set<OpenOption> options = new HashSet<OpenOption>();
options.add(APPEND);
options.add(CREATE);
// Create the custom permissions attribute.
Set<PosixFilePermission> perms =
PosixFilePermissions.fromString("rw-r-----");
FileAttribute<Set<PosixFilePermission>> attr =
PosixFilePermissions.asFileAttribute(perms);
// Convert the string to a ByteBuffer.
String s = "Hello World! ";
byte data[] = s.getBytes();
ByteBuffer bb = ByteBuffer.wrap(data);
Path file = Paths.get("./permissions.log");
try (SeekableByteChannel sbc =
Files.newByteChannel(file, options, attr)) {
sbc.write(bb);
} catch (IOException x) {
System.out.println("Exception thrown: " + x);
}
}
}
上次更新: 2023 年 1 月 25 日