java - 跳过文件的一部分
问题描述
我已经编写了一个代码,它可以让我知道在给定大小的情况下拆分文件的位置。问题是当文件长度发生变化时,我在应该在哪里分割文件时得到不正确的值。
这是代码:(我不确定这是否是确定我应该在哪里拆分文件的最快方法。)
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)
?或BufferedInputStream
的read(buffer,offset,len)
?
解决方案
您在最终字节和长度之间看到的差异是余数。您正在做整数数学,而 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
。
除此之外:
通常,您将引用具有基于 0 的索引的字节(实际上,如果您使用
RandomAccessFile.seek()
它,则会期望从 0 而不是 1 开始的查找位置)所以tmp
用 0 初始化您的变量。我确定您知道,但最后一个分区需要是 end 和 len 的最小值(如果您更改为基于 0 的索引,则为 len - 1)。
推荐阅读
- python-3.x - SeleniumPython3.x 我该如何处理这个元素?
- python - PYTHON 根据键列表更改 json 对象中的值
- javascript - CanvasJS 实时折线图不呈现数据点
- asp.net-core - 如何在 React js 中使用 ServerSideEvent(如果平台是浏览器)的 headers 选项传递请求标头设置
- python - 通过python(flask)在Heroku中运行“docker search”
- html - node_modules 中的一个模块在 node_module 中创建了一个 node_modules 目录
- java - JVM 以编程方式获取堆中最大的对象
- flutter - 颤振构建gradle失败':firebase_core:compileDebugJavaWithJavac'
- javascript - 我如何从这些数据中获取对象数组以获取状态并在 reactjs 中计数
- python - 使用 win10toast 的 Windows 10 通知