首页 > 解决方案 > 跳过文件的一部分

问题描述

我已经编写了一个代码,它可以让我知道在给定大小的情况下拆分文件的位置。问题是当文件长度发生变化时,我在应该在哪里分割文件时得到不正确的值。

这是代码:(我不确定这是否是确定我应该在哪里拆分文件的最快方法。)

long parts = 5L;
long len = 123456L;
long partLen = len / parts;
long tmp = 1L;
for (int i = 0; i < parts; i++) {
    tmp += partLen;
    long start = tmp - partLen;
    long end = tmp - 1L;
    System.out.printf("%d to %d\n", start, end);
}

这将输出:

1 to 24691
24692 to 49382
49383 to 74073
74074 to 98764
98765 to 123455  

这些值是字节。我将使用这些值来读取文件的一部分并将其写入。
前任。读取 1 字节到 24691 字节,然后将其写入文件...

123455不完全是123456。如何添加剩余的字节?
我应该用什么来读取文件,RandomAccessFile's seek()+ read(byte[] b)?或BufferedInputStreamread(buffer,offset,len)

标签: java

解决方案


您在最终字节和长度之间看到的差异是余数。您正在做整数数学,而 len 并没有完全分成几部分。以下结果均返回相同的 partLen 值

System.out.println(123455 / 5);
System.out.println(123456 / 5);
System.out.println(123457 / 5);
System.out.println(123458 / 5);
System.out.println(123459 / 5);

产生以下输出

24691
24691
24691
24691
24691

在计算分区大小时需要考虑到这一点。如果有余数,则分区大小需要大 1。如果没有余数,那么您当前的计算是正确的。

您可以使用其中一个RandomAccessFile,也可以BufferedInputStream根据您要如何处理分区来使用。BufferedInputStream我个人的偏好是在读取分区长度后只打开一次并切换输出文件。但是使用 . 单独处理每个分区并没有错RandomAccessFile

除此之外:

  1. 通常,您将引用具有基于 0 的索引的字节(实际上,如果您使用RandomAccessFile.seek()它,则会期望从 0 而不是 1 开始的查找位置)所以tmp用 0 初始化您的变量。

  2. 我确定您知道,但最后一个分区需要是 end 和 len 的最小值(如果您更改为基于 0 的索引,则为 len - 1)。


推荐阅读