繁体   English   中英

Java中的文件拆分代码无法按要求工作

[英]File Splitting code in Java is not working as required

我已经尝试了以下代码进行文件分割,但是可以正常工作,但未达到要求。 即一个mp3文件名'song.mp3'的大小为2540KB,预期的块数(每个100KB)为25,但是代码仅提供12个块,我不明白原因。

        public static void main(String[] args) throws IOException {

              File file = new File("song.mp3");

    FileInputStream fIn = new FileInputStream("song.mp3");
    FileOutputStream fOut = new FileOutputStream("song_0.mp3");
    int chunk_size = 1024 * 100;
    byte[] buff = new byte[chunk_size]; // 100KB file
    int i = 0;
    String file_name = file.getName();
    String file_name_base = file_name.substring(0, 
    file_name.lastIndexOf("."));
    while (fIn.read() != -1) {

        fIn.read(buff);
        int total_read = 0;
        total_read += chunk_size;
        long read_next_chunk = total_read;
        String file_name_new = file_name_base + "_" + i + ".mp3";
        File file_new = new File(file_name_base);
        i++;
        fOut = new FileOutputStream(file_name_new);
        fOut.write(buff);

        fIn.skip(total_read);// skip the total read part

    } // end of while loop

    fIn.close();
    fOut.close();

}

您的代码确保不起作用,至少是因为:
在每次迭代中,您读取1个字节,并将其丢弃while (fIn.read() != -1)
将循环更改为如下所示:

int bytesReadCounter;
while((bytesReadCounter = fIn.read(buff, 0, chunk_size)) > 0){
    .................................. 
    fOut.write(buff, 0, bytesReadCounter);
    ..................................
}

buff ,存储读取的字节数,在bytesReadCounter存储读取的字节数。
然后你写fOutbuff正是bytesReadCounter字节。

编辑 ,使用此代码:

public static void main(String[] args) {
    File file = new File("song.mp3");

    FileInputStream fIn = null;
    try {
        fIn = new FileInputStream(file);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    int chunk_size = 1024 * 100;
    byte[] buff = new byte[chunk_size]; // 100KB file
    int i = 0;
    String file_name = file.getName();
    String file_name_base = file_name.substring(0, file_name.lastIndexOf("."));
    int bytesReadCounter;
    boolean hasMore = true;
    while (hasMore) {
        try {
            bytesReadCounter = fIn.read(buff, 0, chunk_size);
        } catch (IOException e) {
            e.printStackTrace();
            break;
        }

        hasMore = bytesReadCounter > 0;

        if (!hasMore)
            break;

        String file_name_new = file_name_base + "_" + i + ".mp3";
        File file_new = new File(file_name_new);

        FileOutputStream fOut = null;
        try {
            fOut = new FileOutputStream(file_new);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            break;
        }

        try {
            fOut.write(buff, 0, bytesReadCounter);
            fOut.close();
        } catch (IOException e) {
            e.printStackTrace();
            break;
        }

        i++;
    }

    try {
        fIn.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

我想立即提出较新的Path/Files类。

以下代码未经测试,但具有清晰的缓冲读取:

  • 顺序读取原始文件
  • 循环零件
  • 使用缓冲区( block )编写部分-比仅仅FileInputStream更快

所以:

public static void splitFile(String file) throws IOException {
    final long partSize = 100 * 1024;

    Path originalPath = Paths.get(file);
    if (Files.isReadable(originalPath)) {
        throw new FileNotFoundException("Is not a readable file: " + originalPath);
    }
    // Read the file:
    long totalSizeToRead = Files.size(originalPath);
    try (InputStream in = Files.newInputStream(originalPath)) {
        int partNo = 0;
        byte[] block = new byte[16 * 1024];
        // Write parts
        while (totalSizeToRead > 0) {
            // Write part
            ++partNo;
            Path partPath = Paths.get(String.format("%s-%03d.part", file, partNo));
            int sizeToReadInPart = partSize;
            if (totalSizeToRead < sizeToReadInPart) {
                sizeToReadInPart = (int) totalSizeToRead;
            }
            try (OutputStream out = Files.newOutputStream(partPath,
                                    StandardOpenOptions.REPLACE_EXISTING)) {
                // Write blocks of part
                while (sizeToReadInPart > 0) {
                    int toRead = Math.min(block.length, sizeToReadInPart);
                    int actuallyRead = in.read(block, 0, toRead);
                    sizeToReadInPart -= actuallyRead;
                    if (actuallyRead <= 0) {
                        break;
                    }
                    out.write(block, 0, actuallyRead);
                }
            }
            totalSizeToRead -= sizeToReadInPart;
        }
    }
}

这里的要点:

  • try-with-resource即使在发生返回/中断/抛出异常时也会自动关闭。
  • 我使用文件大小(长整型)和int作为缓冲区大小,需要注意一些。 同样,它是一个冗余,给定actuallyRead
  • Java按照惯例使用camelCase代替普通变量使用下划线。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM