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

Java中的文件拆分代码未按要求工作,java,file-io,Java,File Io,我已经尝试了下面的文件拆分代码,它可以工作,但不符合要求。 i、 一个mp3文件名“song.mp3”的大小为2540KB,预期100KB的块数为25个,但代码只给出12个块,我不明白原因 public static void main(String[] args) throws IOException { File file = new File("song.mp3"); FileInputStream fIn = new FileInp

我已经尝试了下面的文件拆分代码,它可以工作,但不符合要求。 i、 一个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个字节,然后在fIn.read!=-1. 将循环更改为以下内容:

int bytesReadCounter;
while((bytesReadCounter = fIn.read(buff, 0, chunk_size)) > 0){
    .................................. 
    fOut.write(buff, 0, bytesReadCounter);
    ..................................
}
在buff中存储读取的字节数,在ByteReadCounter中存储读取的字节数。 然后从buff向fOut写入bytesReadCounter字节

编辑,使用以下代码:


我想马上提出更新的课程

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

按顺序读取原始文件 把零件圈起来 使用缓冲区块编写一个部件-这比单纯的FileInputStream要快 因此:

这里的要点是:

try with resource自动关闭,即使在返回/中断/抛出异常时也是如此。 我使用文件大小Long和int表示缓冲区大小,需要注意。此外,考虑到实际读数,这也是一种冗余。 Java按惯例对普通变量使用camelCase而不是下划线。
您得到的块是否代表整个原始文件?你在什么地方出错了吗?而fIn.read!=-1,然后是fIn.readbuff。你明白你在做什么吗?是的,我知道我在做什么。我没有从这个代码中得到任何错误。如果输入文件中没有要读取的内容,则fIn.read返回-1。我想循环阅读整个文件,直到它结束。我做错什么了吗?plz指南。我想模拟一个云存储BLOB,我的应用程序将大文件保存在大小为50-100KB的小块中,我将每个块的哈希保存在本地以进行完整性检查。fIn.read:从这个输入流读取一个字节的数据您正在读取1KB,并将1KB写入输出文件。我知道在每次迭代中读取100KB的循环条件是错误的。一种选择是将整个文件读入缓冲区,然后使用skip方法在缓冲区上迭代以写出它。上面的代码在每次迭代时读取chunk_大小的字节,而不会丢失任何数据。当然,在最后一次迭代中,可能会有小于chunk_大小的字节。我可以从指定的字节位置通过FileInputStream读取文件吗?上面的代码表示我的。不,你不能。你必须从头读到你想读的那一点,先生。非常感谢您的帮助,我还没有理解完整的代码,但它可以工作。我会告诉你我有任何疑问。再次感谢。谢谢@Joop Eggen我一定会尝试一下,它比我的计算效率高吗?
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();
    }
}
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;
        }
    }
}