使用 MappedByteBuffer 时出现 IndexOutOfBoundsException
Posted
技术标签:
【中文标题】使用 MappedByteBuffer 时出现 IndexOutOfBoundsException【英文标题】:IndexOutOfBoundsException when use MappedByteBuffer 【发布时间】:2017-07-25 21:38:08 【问题描述】:我正在考虑使用 MappedByteBuffer 将一些数据存储/加载到文件中。假设我有 long 类型的字段 A 和字符串的字段 B 在序列化时如下所示: A(长) | B(字符串)
现在我想写和读它。这是一段示例代码:
RandomAccessFile file = new RandomAccessFile(dataPath.toString(), "rw");
MappedByteBuffer mbb = file.getChannel().map(FileChannel.MapMode
.READ_WRITE, 0, 256);
long num = 500;
mbb.putLong(0, num); // (1) first write the long value at beginning
String str = "Hello World!";
byte[] input = str.getBytes();
//then write a string
mbb.put(input, 8, input.length); // (2) IndexOutOfBoundsException
所以以后我可以通过调用mbb.getLong(0)
来检索 long
和mbb.get(outputArray,8,outputArray.length)
但现在我在地方 (2) 失败了。有什么建议吗?
【问题讨论】:
你必须输入0
而不是0
,因为你的字节数组从零开始
另请注意:您将无法在阅读时使用outputArray.length
- 您不知道要分配多少
@IlyaBursov 谢谢!对于您的第一点...这是因为我希望字符串成为从 pos 8 开始的第二个字段。对于第二点,我可以指定 MAX_LEN 的上限,我知道我的字符串不会长于那个并且读入那个缓冲区?
put
的第二个参数在源数组中偏移,而不是在目标缓冲区中
@IlyaBursov 我明白了。谢谢。那么在指定位置将字节数组(src)放入当前缓冲区(dst)的建议方法是什么?总是必须调用 mbb.position(index) 来设置它,比如在 8?
【参考方案1】:
试试
mbb.put(destArray, 0, sourceArray.length)
我认为您不想从 8 字节偏移量开始写入,否则您会尝试在数组的长度上写入 8 个字节。
【讨论】:
感谢您的回复。但我打算保留一个映射到文件的 long, string 结构。即我总是在 pos 8 检索字符串。我错过了什么吗? 假设您有一个长度为 10 的数组,当您尝试从偏移量 8 开始写入 10 个字节 (array.length) 时会发生什么?在超出范围之前您只有 2 个字节。 谢谢先生。现在我明白你的意思了。您的意思是说偏移量是针对 src 字节数组(代码中的 outputArray 和我的情况下的输入)? 我更新了答案,偏移量是您开始写入目标数组的位置。 另外,请注意,当您在示例中说byte[] input = str.getBytes();
时,您正在创建大小为 12 的数组....所以当您从偏移量 8 开始写入时,您只有 4 个字节才能出去界限。以上是关于使用 MappedByteBuffer 时出现 IndexOutOfBoundsException的主要内容,如果未能解决你的问题,请参考以下文章
在 stm32f769i-Discovery 上使用 BSP 库进行录音时出现问题
使用 glvertex4i 传递网格面索引时出现顶点着色器错误
使用 glvertex4i 传递网格面索引时出现顶点着色器错误
使用 aspnet_regiis -i 时出现“dns server not authoritative for zone”错误