在Java中拆分并返回一个二进制文件

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (108)

我试图将二进制文件(比如视频/音频/图像)分成100kb的块,然后将这些块加回去以获取原始文件。我的代码似乎在工作,从它分割文件并加入块的意义上说,我找回的文件与原始文件大小相同。然而,问题在于内容被截断 - 也就是说,如果它是一个视频文件,它会在2秒后停止,如果它是图像文件,则只有上半部分看起来正确。

这里是我使用的代码(如果你喜欢,我可以发布整个代码):

划分:

File ifile = new File(fname); 
FileInputStream fis;
String newName;
FileOutputStream chunk;
int fileSize = (int) ifile.length();
int nChunks = 0, read = 0, readLength = Chunk_Size;
byte[] byteChunk;
try {
    fis = new FileInputStream(ifile);
    StupidTest.size = (int)ifile.length();
    while (fileSize > 0) {
        if (fileSize <= Chunk_Size) {
            readLength = fileSize;
        }
        byteChunk = new byte[readLength];
        read = fis.read(byteChunk, 0, readLength);
        fileSize -= read;
        assert(read==byteChunk.length);
        nChunks++;
        newName = fname + ".part" + Integer.toString(nChunks - 1);
        chunk = new FileOutputStream(new File(newName));
        chunk.write(byteChunk);
        chunk.flush();
        chunk.close();
        byteChunk = null;
        chunk = null;
    }
    fis.close();
    fis = null;

对于加入文件,我将所有块的名称放入列表中,然后按名称对其进行排序,然后运行以下代码:

File ofile = new File(fname);
FileOutputStream fos;
FileInputStream fis;
byte[] fileBytes;
int bytesRead = 0;
try {
    fos = new FileOutputStream(ofile,true);             
    for (File file : files) {
        fis = new FileInputStream(file);
        fileBytes = new byte[(int) file.length()];
        bytesRead = fis.read(fileBytes, 0,(int)  file.length());
        assert(bytesRead == fileBytes.length);
        assert(bytesRead == (int) file.length());
        fos.write(fileBytes);
        fos.flush();
        fileBytes = null;
        fis.close();
        fis = null;
    }
    fos.close();
    fos = null;
提问于
用户回答回答于

我只能在代码中发现两个潜在的错误:

int fileSize = (int) ifile.length();

上面的文件超过2GB时失败,因为int无法保存更多文件。

newName = fname + ".part" + Integer.toString(nChunks - 1);

一个像这样构造的文件名应该以非常特定的方式排序。使用默认的字符串排序时,name.part10就会前来name.part2。您希望提供一个自定义Comparator,它将提取并分析零件编号为int,然后通过它进行比较。

用户回答回答于

对于加入文件,我将所有块的名称放入列表中,然后按名称对其进行排序,然后运行以下代码:

但是你的名字的形式如下:

newName = fname + ".part" + Integer.toString(nChunks - 1);

仔细考虑如果您有11个或更多零件会发生什么情况。哪个字符串按字母顺序排在第一位:“.part10”或“.part2”?(答案:“.part10”,因为'1'在字符编码中位于'2'之前。)

扫码关注云+社区