Java文件操作:读取、复制与随机访问
立即解锁
发布时间: 2025-08-18 02:26:25 阅读量: 2 订阅数: 18 

### Java 文件操作:读取、复制与随机访问
#### 1. 文件读取机制
在文件读取操作中,为了确保完整读取文件内容并处理剩余数据,我们采用特定的缓冲区策略。具体步骤如下:
1. **创建直接缓冲区**:使用 `allocateDirect()` 方法创建一个容量为 256 字节的直接缓冲区。直接缓冲区在大量读取文件数据时速度更快,因为数据可直接从文件传输到缓冲区。
2. **循环处理数据**:在无限 `while` 循环中进行数据处理。循环开始前,将缓冲区的位置设置为限制位置,使 `remaining()` 方法在首次循环开始时返回 0。
3. **检查数据长度**:循环内首先检查缓冲区中是否有足够的字节来存储指定字符串长度的双精度值。若不足,则调用 `compact()` 方法压缩缓冲区,并将返回的 `buf` 引用传递给 `inCh` 的 `read()` 方法从文件读取数据。
4. **获取字符串和二进制素数值**:翻转缓冲区获取字符串长度,接着获取字符串本身,若检测到文件结束符(EOF)则输出错误信息。最后,以类似方式获取二进制素数值并输出这三个数据项。循环持续进行,直到读取并处理完所有数据,且在查找字符串长度值时识别到 EOF。
#### 2. 文件复制方法
除了使用 `Files` 类的 `copy()` 方法复制文件,还可使用 `FileChannel` 对象实现文件复制,这种方式能直接在通道间传输数据,无需显式缓冲区。`FileChannel` 类定义了两个高效的数据传输方法:
| 方法 | 描述 |
| --- | --- |
| `transferTo(long position, long count, WritableByteChannel dst)` | 尝试将 `count` 字节从当前通道传输到目标通道 `dst`。从指定的文件位置 `position` 开始读取字节,当前通道位置不变,目标通道位置会根据写入字节数增加。若当前通道文件剩余字节少于 `count` 或目标通道非阻塞且系统输出缓冲区可用字节少于 `count`,则传输字节数可能少于 `count`。该方法返回传输的字节数。 |
| `transferFrom(ReadableByteChannel src, long position, long count)` | 尝试从源通道 `src` 向当前通道传输 `count` 字节。从指定的文件位置 `position` 开始写入字节,当前通道位置不变,源通道位置会根据读取字节数增加。若 `position` 大于文件大小,则不传输字节。若源通道文件剩余字节少于 `count` 或源通道非阻塞且系统输入缓冲区可用字节少于 `count`,则传输字节数可能少于 `count`。该方法返回传输的字节数。 |
这两个方法可能抛出以下异常:
- `IllegalArgumentException`:若 `count` 或 `position` 为负数。
- `NonReadableChannelException`:尝试从未以读取模式打开的通道读取数据。
- `NonWritableChannelException`:尝试向未以写入模式打开的通道写入数据。
- `ClosedChannelException`:操作涉及的通道已关闭。
- `AsynchronousCloseException`:操作进行中,通道被其他线程关闭。
- `ClosedByInterruptException`:操作进行中,当前线程被其他线程中断。
- `IOException`:发生其他 I/O 错误。
以下是一个使用 `FileChannel` 复制文件的示例代码:
```java
import static java.nio.file.StandardOpenOption.*;
import java.nio.file.*;
import java.nio.channels.*;
import java.io.IOException;
import java.util.EnumSet;
public class FileBackup {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("No file to copy. Application usage is:\n" +
"java -classpath . FileCopy \"filepath\"");
System.exit(1);
}
Path fromFile = Paths.get(args[0]);
fromFile.toAbsolutePath();
if (Files.notExists(fromFile)) {
System.out.printf("File to copy, %s, does not exist.", fromFile);
System.exit(1);
}
Path toFile = createBackupFilePath(fromFile);
try (FileChannel inCh = (FileChannel) (Files.newByteChannel(fromFile));
WritableByteChannel outCh = Files.newByteChannel(
toFile, EnumSet.of(WRITE, CREATE_NEW))) {
int bytesWritten = 0;
long byteCount = inCh.size();
while (bytesWritten < byteCount) {
bytesWritten += inCh.transferTo(bytesWritten,
byteCount - bytesWritten,
outCh);
}
System.out.printf(
"File copy complete. %d bytes copied to %s%n", byteCount, toFile);
} catch (IOException e) {
e.printStackTrace();
}
}
// Method to create a unique backup Path object under MS Windows
public static Path createBackupFilePath(Path file) {
Path parent = file.getParent();
String name = file.getFileName().toString(); // Get the file name
int period = name.indexOf('.'); // Find the extension separator
if (period == -1) { // If there isn't one
period = name.length(); // set
```
0
0
复制全文
相关推荐










