Java 从一个文件通道复制到另一个文件通道

Java 从一个文件通道复制到另一个文件通道,java,io,stream,Java,Io,Stream,我试图将一个文件的一部分从一个filechannel复制到另一个filechannel(编写一个新文件,实际上等于第一个文件) 所以,我在读256kb的块,然后把它们放回另一个频道 static void openfile(String str) throws FileNotFoundException, IOException { int size=262144; FileInputStream fis = new FileInputStream(str); FileC

我试图将一个文件的一部分从一个filechannel复制到另一个filechannel(编写一个新文件,实际上等于第一个文件)

所以,我在读256kb的块,然后把它们放回另一个频道

static void openfile(String str) throws FileNotFoundException, IOException {
    int size=262144;
    FileInputStream fis = new FileInputStream(str);
    FileChannel fc = fis.getChannel();
    byte[] barray = new byte[size];
    ByteBuffer bb = ByteBuffer.wrap(barray);

    FileOutputStream fos = new FileOutputStream(str+"2" /**/);
    FileChannel fo = fos.getChannel();

    StringBuilder sb;
    while (fc.read(bb) != -1) {            
        fo.write(bb /**/);            
        bb.clear();
    }
}
问题是fo.write(我认为)从通道的开头再次写入,因此新文件仅由最后读取的块组成

我尝试了
fo.write(bb,bb.position())
但它没有像我预期的那样工作(指针是否返回到通道的开头?)和
FileOutputStream(str+“2”,true)
认为它会附加到新文件的末尾,但没有

我需要处理256kb的块,所以我不能改变程序的结构(除非我做了一些非常错误的事情)


bb.flip()解析


在通道之间复制的标准方式如下所示:

while (in.read(bb) > 0 || bb.position() > 0)
{
    bb.flip();
    out.write(bb);
    bb.compact();
}

您编辑的答案中的简化版本并非在所有情况下都有效,例如,当“out”为非阻塞时。

这是一个非常古老的问题,但我偶然发现了它,尽管我可能会添加另一个答案,该答案使用或可能具有更好的性能。根据javadoc:

此方法可能比从源通道读取并写入此通道的简单循环更有效。许多操作系统可以直接将字节从源通道传输到文件系统缓存,而无需实际复制它们

publicstaticvoidcopy(filechannelsrc,filechanneldst)抛出IOException{
长尺寸=src.size();
长转移=0;
做{
转移+=src.transferTo(0,大小,dst);
}while(转移<大小);
}

在大多数情况下,一个简单的
src.transferTo(0,src.size(),dst)将起作用。

为什么必须使用FileChannel?也许这就是你要找的?因为我找到了这篇文章。我正在检查那个。应该足够了。相关?第一篇文章的问题是,它传输所有内容,而不是块。现在检查RC的解决方案似乎我必须使用bb.flip();如果你写下来,我会接受答案。你说的不阻塞是什么意思?查一查。一些通道,例如
SocketChannels,
可以被置于非阻塞模式,这意味着
write()
可以在没有写入所有数据或任何数据的情况下返回。这使得
compact()
必不可少,而不是
clear()
,并且在流的末尾对
position()>0
进行额外的测试也必不可少。
while (in.read(bb) > 0 || bb.position() > 0)
{
    bb.flip();
    out.write(bb);
    bb.compact();
}
public static void copy(FileChannel src, FileChannel dst) throws IOException {
    long size = src.size();
    long transferred = 0;
    do {
        transferred += src.transferTo(0, size, dst);
    } while (transferred < size);
}