0

I'm trying to copy part of a file from a filechannel to another (writing a new file, in effect, equals to the first one).

So, I'm reading chunks of 256kb, then putting them back into another channel

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();
    }
}

The problem is that fo.write (I think) writes again from the beginning of the channel, so the new file is made only of the last chunk read.

I tried with fo.write (bb, bb.position()) but it didn't work as I expected (does the pointer returns to the beginning of the channel?) and with FileOutputStream(str+"2", true) thinking it would append to the end of the new file, but it didn't.

I need to work with chunks of 256kb, so I can't change much the structure of the program (unless I am doing something terribly wrong)


Resolved with bb.flip();

while (fi.read(bb) != -1) {
        bb.flip();
        fo.write(bb);
        bb.clear();
    }
4

2 回答 2

0

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

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

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);
}

在大多数情况下,src.transferTo(0, src.size(), dst); 如果没有通道是非阻塞的,那么一个简单的方法就可以工作。

于 2014-04-16T11:51:04.950 回答
0

在通道之间复制的规范方法如下:

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

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

于 2013-10-13T22:31:24.440 回答