我编写了这段代码,将文件分成多个块。该程序适用于大小为12KB且块大小为8KB的文件。但是,当我给出一个2980144字节的输入文件大小时,它会进入旋转状态 - 永远不会出现。
是否与输入文件的大小和要访问的FileChannel问题有关?我想使用这个程序将较大的文件(二进制形式)分成多个块,以便通过网络轻松传输。我将块大小保留为参数,以便我可以根据需要进行配置。
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;
}
答案 0 :(得分:1)
发现了这个问题。循环有问题。下面是正确的循环。
while (bytesRead >= 0) {
bytesRead = splitter.GetNextChunk(offset);
if (bytesRead == -1)
break;
offset += bytesRead;
System.out.println("Byte offset is: " + offset);
}
答案 1 :(得分:1)
它并不像你制作它那么难。你的代码大约是它需要的十倍。试试这个:
while (in.read(buffer) > 0 || buffer.position() > 0)
{
buffer.flip();
out.write(buffer);
buffer.compact();
}
如果'out'是SocketChannel,它将以最大速度通过网络发送文件。
你不需要一个monstro缓冲区,但你应该总是使用2的幂。我通常使用8192.