【Java】 FileChannel类来实现文件之间的数据传输

简单示例

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
String FROM = "data.txt"; // 文件路径
String TO = "to.txt";
try (FileChannel from = new FileInputStream(FROM).getChannel();
     FileChannel to = new FileOutputStream(TO).getChannel();
    ) 
{
    from.transferTo(0, from.size(), to);
} catch (IOException e) {
    e.printStackTrace();
}

在try语句块中,通过调用from.transferTo()方法将数据从源文件通道(from)传输到目标文件通道(to)。该方法的第一个参数是源文件通道的起始位置,这里设置为0,表示从文件的开头开始传输。第二个参数是要传输的字节数,这里使用from.size()获取源文件的大小。第三个参数是目标文件通道。

超过2G大小的文件传输

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class TestFileChannelTransferTo {
    public static void main(String[] args) {
        try (
                FileChannel from = new FileInputStream("data.txt").getChannel();
                FileChannel to = new FileOutputStream("to.txt").getChannel();
        ) {
            // 效率高,底层会利用操作系统的零拷贝进行优化, 一次最多传输2G数据
            long size = from.size();
            // left 变量代表还剩余多少字节
            for (long left = size; left > 0; ) { // 多次传输,以解决最多传输2G的问题
                System.out.println("position:" + (size - left) + " left:" + left);
                left -= from.transferTo((size - left), left, to); // 减去实际传输的字节数量
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

创建一个FileInputStream对象和一个FileOutputStream对象,并通过它们的getChannel()方法获取对应的FileChannel对象。
循环传输文件数据,直到剩余字节数left为0。
在每次循环中,通过调用from.transferTo()方法将数据从源文件通道(from)传输到目标文件通道(to)。

  • 第一个参数是源文件通道的当前位置,这里使用(size - left)来设置位置,确保从文件的剩余部分的开始进行传输。
  • 第二个参数是每次传输的最大字节数,这里使用left,表示剩余字节数。
  • 第三个参数是目标文件通道,即要传输到的文件通道。

通过减去实际传输的字节数量left,更新剩余字节数。

如果在传输过程中发生IOException异常,会捕获并打印异常信息。

这段代码的目的是将一个名为"data.txt"的文件的数据传输到另一个名为"to.txt"的文件中。它使用了FileChannel的transferTo()方法来实现高效的数据传输,利用操作系统的零拷贝机制进行优化。每次传输的数据量最大为2G,通过多次传输来解决超过2G的数据量的问题。

参考:https://www.bilibili.com/video/BV1py4y1E7oA?p=16

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用RandomAccessFile和MappedByteBuffer实现Java SocketChannel文件分块随机传输的示例代码: ```java import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.SocketChannel; public class FileTransferExample { private static final int CHUNK_SIZE = 1024; // 每次传输的块大小 public static void main(String[] args) { try { // 创建RandomAccessFile对象 RandomAccessFile file = new RandomAccessFile("path/to/file", "r"); // 获取文件通道 FileChannel fileChannel = file.getChannel(); // 创建SocketChannel对象,连接到目标主机和端口 SocketChannel socketChannel = SocketChannel.open(); socketChannel.connect(serverAddress); // 设置文件指针的位置,即要传输的文件的起始位置 long position = 0; while (position < file.length()) { // 计算当前块的大小 long remaining = file.length() - position; int chunkSize = (int) Math.min(remaining, CHUNK_SIZE); // 创建MappedByteBuffer对象,将文件的一部分映射到内存中 MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, position, chunkSize); // 通过SocketChannel的write()方法将MappedByteBuffer中的数据写入到网络通道中 while (buffer.hasRemaining()) { socketChannel.write(buffer); } // 更新文件指针的位置 position += chunkSize; } // 关闭SocketChannel和RandomAccessFile socketChannel.close(); file.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 请注意,上述代码中的`path/to/file`需要替换为实际的文件路径,`serverAddress`需要替换为目标主机和端口。此外,还需要处理异常和错误情况,以确保文件传输的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值