问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

仅支持transfer和transferfrom方法

发布网友 发布时间:2023-03-06 10:54

我来回答

3个回答

热心网友 时间:2023-06-23 07:06

FileChannel中提供了两个方法 transferFrom(ReadableByteChannel src, long position, long count) 和 transferTo(long position, long count, WritableByteChannel target)用于两个通道间的数据传输,通常使用单线程进行传输的时候这两个方法不会出现什么问题, 但是 当我使用多线程方式 进行文件的复制的时候, transferFrom 方法最后传输的总是 count的长度(count是每个线程平均分配处理的长度).

热心网友 时间:2023-06-23 07:06

transferTo()和transferFrom()方法使您可以将一个通道交叉连接到另一个通道,而无需通过中间缓冲区传递数据。

热心网友 时间:2023-06-23 07:07

按照此需求,常规方式,我们使用如下代码来完成:

File file = new File("D:\\test.txt");
Long size = file.length();
byte[] arr = new byte[size.intValue()];

try {
// 1.将test.txt文件内容读取到arr中
FileInputStream fileInputStream = new FileInputStream(file);
fileInputStream.read(arr);

// 2.提供对外服务
Socket socket = new ServerSocket(9999).accept();

// 3.传输到客户端
socket.getOutputStream().write(arr);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
以上是一个最简单版本的实现。

那么从操作系统的角度,以上传输经历了哪些过程呢?

这中间的过程我们可以分为以下几步:
fileInputStream.read方法对应于:
1)第一次复制:read方法调用,用户态切换到内核态。数据从硬盘拷贝到内核缓冲区,基于DMA自动操作,不需要CPU支持
2)第二次复制:从内核缓冲区拷贝到用户缓冲区(也就是byte[] arr中)。read方法返回,用内核态到用户态的转换。
socket.getOutputStream().write(arr)对应于:
3)第三次复制:从用户缓冲区拷贝数据到socket的内核缓冲区。write方法调用,用户态切换到内核态。
4)数据从socket内核缓冲区,使用DMA拷贝到网络协议引擎。write方法返回,内核态切换到用户态。
从上面的过程我们可以发现,数据发生了四次拷贝,四次上下文切换。
那么还有没有优化方式呢?答案是肯定的,我们接着往下看。
2.mmap优化
mmap通过内存映射,将文件直接映射到内存中。此时,用户空间和内核空间可以共享这段内存空间的内容。用户对内存内容的修改可以直接反馈到磁盘文件上。
FileChannel提供了map方法来实现mmap功能
File file = new File("D:\\test.txt");
Long size = file.length();
byte[] arr = new byte[size.intValue()];

try {
// 1.将test.txt文件内容读取到arr中
RandomAccessFile raFile = new RandomAccessFile(file, "rwd");
FileChannel channel = raFile.getChannel();
MappedByteBuffer mappedByteBuffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, size);

// 2.提供对外服务
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

serverSocketChannel.socket().bind(new InetSocketAddress(9999));
serverSocketChannel.configureBlocking(false);

while(true){
SocketChannel socketChannel =
serverSocketChannel.accept();

if(socketChannel != null){
// 3.传输到客户端
socketChannel.write(mappedByteBuffer);
}
}

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
我们直接将file的内容映射到mappedByteBuffer,然后直接将mappedByteBuffer的内容传递出去
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
QQ空间里的好多东西怎么删不掉阿 我想把QQ上的文件全删掉,为什么有的删不掉呢。 4M宽带为什么有1M的下载速度 有什么办法治疗牙结石?还有晚上牙龈出血?有什么食物可以补充营养?曾经... 红米Note2开机以后不显示桌面但是有图标下面三个键都不好使您知道怎么... 红米Note2,酷我音乐盒桌面歌词没有,已经设置了,悬浮窗什么的也点... 大神们, 帮忙把下面文字翻译成英文吧! 急~~~ 机器君就算了 多谢啊 O... DIN 54801-2006 是德国什么标准 我想问一下" high melt viscosity at low shear rates"是什么意思? 请问谁有《喜羊羊与灰太狼》中,灰太狼说的“我一定会回来的”,和懒羊... 阵字加一笔或剪一笔是什么字 123456的2+1个竖折折钩是什么字呢 14年桑塔纳最低配能改电动开启后备箱吗 05捷达能改电动后备箱吗 逍客后备箱能改成电动门吗 耳朵打洞十来年为什么会臭 耳朵洞有异味 农村合作化运动是如何发展的呢? 燃气双项管道是什么意思啊 单项式和双项式是什么意思?我分不清楚。 双项选择是什么意思 手机怎么多张图片合成长图 用苹果手机充优酷会员没有交易记录怎么办,现在需要用这个交易信息_百度... 三个月大的宝宝肠胃热吃什么药可以好 宝宝有胃热,肠热怎么来调理最好的 秋冬宝宝易上火 饮食调理去肠热 脑出血的并发症常见有哪些 墨墨背单词注销怎么查id 慢性胃炎常见胃肠病的药物治疗有哪些 猫长期不洗澡会怎样(猫可以一直不洗澡么) 电信橙分下月生效吗 战队管理公告怎么设计? 如何进行程序查询方式? 营业厅情况如何查询? 灵活就业社保查询如何进行? 猪脚酸姜的家常做法大全怎么做好吃视频 规范使用监理工程师通知单? 狮子头是哪里的特产 宁夏滩羊肉在网上能买到吗 去宁夏必买的十大特产 初级工程师能评教师职称吗 初级通信工程师如何评职称 换iphone怎么资料备份导入 怎么注销 电脑麦克风怎么连接 如何注销掉 微信不用了如何注销 未成年微信余额怎么解封冻结 女孩考验男生的10个套路 混凝土添加剂洒身体上有什么害处