java - 使用 RamdomAccesFile 和 FileChannel 对文件进行分块时出现问题

标签 java file-io java-7 nio

我编写了这段代码来将文件分成多个 block 。该程序对于大小为 12KB、 block 大小为 8KB 的文件运行良好。然而,当我给出 2980144 字节的输入文件大小时,它会进入旋转状态 - 永远不会出来。

输入文件的大小和要访问的 FileChannel 问题是否与此有关?我想使用这个程序将较大的文件(二进制形式)分成多个 block ,以便于通过网络传输。我保留了 block 大小作为参数,以便我可以根据要求进行配置。

public static void main(String[] args) {

    int chunkSize = 8000;

    long offset = 0;
    while (offset >= 0) {
        offset = splitter.GetNextChunk(offset);
    }
}

public long GetNextChunk(long offset) {

    long bytesRead = 0;
    ByteBuffer tmpBuf = ByteBuffer.allocate(chunkSize);
    RandomAccessFile outFile = null;
    RandomAccessFile inFile = null;
    FileChannel inFC = null;
    FileChannel outFC = null;

    try {
        inFile = new RandomAccessFile(inFileName, "r");
        inFC = inFile.getChannel();
        tmpBuf.clear();

        // Seek to the offset in the file
        inFC.position(offset);

        // Read the specified number of bytes into the buffer.  
        do {
            bytesRead = inFC.read(tmpBuf);
        } while (bytesRead != -1 && tmpBuf.hasRemaining());

        // Write the copied bytes into a new file (chunk).
        String outFileName = outFolder + File.separator + "Chunk" + String.valueOf(chunkCounter++) + ".dat";
        outFile = new RandomAccessFile(outFileName, "rw");
        outFC = outFile.getChannel();

        outFC.position(0);
        tmpBuf.flip();

        while(tmpBuf.hasRemaining()) {
            outFC.write(tmpBuf);
        }

        // Reposition the buffer to 0.
        tmpBuf.rewind();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
        try {
            if (inFC != null)
                inFile.close();

            if (outFC != null)
                outFile.close();

            if (inFC != null)
                inFC.close();

            if (outFC != null)
                outFC.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    return bytesRead;
}

最佳答案

发现问题了。环路有故障。下面是正确的循环。

    while (bytesRead >= 0) {
        bytesRead = splitter.GetNextChunk(offset);

        if (bytesRead == -1)
            break;

        offset += bytesRead;
        System.out.println("Byte offset is: " + offset);
    }

关于java - 使用 RamdomAccesFile 和 FileChannel 对文件进行分块时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24665852/

相关文章:

java - 将一些代码放在 try catch block 中可以通过哪些方式阻止 JVM 进行优化?

c++ - 复制另一个进程正在使用的文件

c - 使用 fgets 在 C 中检测 EOL

android - 错误 : Default interface methods are only supported starting with Nougat (--min-api 24) when NOT using them

java - 将 BinarySecurityToken 添加到 cxf header

java - Hadoop “Unable to load native-hadoop library for your platform”警告

c++ - 从我的二维数组中的一列返回的字符串值被压缩成一个字符串(在 Mac 操作系统上打开 Windows txt 文件)

java - 在 Java 中用字符串切换大小写 - 垃圾?

java - 用于 AWT/Swing 的 Java JDK 1.7 中的 Apple Retina 显示支持

java - 使用 Javassist 添加语句