为什么FileChannel.map会占用Integer.MAX_VALUE数据?

时间:2011-11-10 08:06:10

标签: java io nio

使用FileChannel.map

时出现以下异常
Exception in thread "main" java.lang.IllegalArgumentException: Size exceeds Integer.MAX_VALUE
    at sun.nio.ch.FileChannelImpl.map(Unknown Source)
    at niotest.NioTest.readUsingNio(NioTest.java:38)
    at niotest.NioTest.main(NioTest.java:64)

快速查看OpenJdk实现显示FileChannelImpl中的方法map(..)将size类型long作为输入。但是在体内,它将它与Integer.MAX_VALUE进行比较,如果它大于那个则抛出错误。为什么将long大小作为输入,但将其限制为最大integer长度?

有谁知道这个实施背后的具体原因? 还是某种虫子?

来源网址 - http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/nio/ch/FileChannelImpl.java

我在64位Windows-2k8上使用64位JRE运行此程序

2 个答案:

答案 0 :(得分:6)

这不是特定于实现的错误。大小在FileChannel.map中定义为long,但是......

  

size - 要映射的区域的大小;必须是非负数且不大于Integer.MAX_VALUE

所有兼容的JVM实现都是这样的。我怀疑原因是历史的组合(谁需要访问大于2GB的文件?;)并试图在更高版本的Java中推进事情(允许大于Integer.MAX的值比允许的更容易将数据类型从int更改为long。)

很多人在Java API中发现这种基于int的思想,关于任何文件非常混乱和短视。但请记住,Java在1995年开始开发!我敢肯定当时2GB似乎是一个相对安全的价值。

答案 1 :(得分:3)

ByteBuffer的容量仅限于Integer.MAX_VALUE,因此无法映射大于此值的任何内容。

看看:MappedByteBuffer map(MapMode mode, long position, long size)
由于显而易见的原因,position必须很长 size不需要很长,但在任何计算中都必须提升 - 例如,位置+大小必须是正长。操作系统映射确实可以使用long来进行映射,map函数(mmap)可能需要映射多于Integer.MAX_VALUE才能保留页面大小,但ByteBuffer只是不能使用它。

整体int在java的设计中非常深入,并且没有size_t C类似的类型,使用long而不是int的质量将阻碍性能。所以最后:如果您需要比2GB更大的地图,只需使用多个ByteBuffer。