为什么FileChannel.map会占用Integer.MAX_VALUE数据?
我在使用FileChannel.map时遇到exception
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(..)将long
类型的size
作为输入。 但是在体内,它将它与Integer.MAX_VALUE
进行比较,如果它大于那,则抛出错误。 为什么将long
尺寸作为输入但是将其限制为最大integer
长度?
有谁知道这个实现背后的具体原因? 还是某种虫子?
源URL – http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/nio/ch/FileChannelImpl.java
我在64位Windows-2k8上使用64位JRE运行此程序
这不是特定于实现的错误。 大小在FileChannel.map中定义为long,但是……
size – 要映射的区域的大小; 必须是非负数且不大于Integer.MAX_VALUE
所有兼容的JVM实现都是这样的。 我怀疑原因是历史的组合(谁需要访问大于2GB的文件?;)并试图在更高版本的Java中推进事情(允许大于Integer.MAX
值比将更容易是将数据类型从int
更改为long
。)
很多人在Java API中发现这种基于int的思想有关任何文件非常混乱和短视。 但请记住,Java在1995年开始开发! 我相信当时2GB似乎是一个相对安全的价值。
ByteBuffer的容量限制为Integer.MAX_VALUE,因此无法映射大于此值的任何内容。
看看: MappedByteBuffer map(MapMode mode, long position, long size)
由于显而易见的原因, position
必须很长。
size
不必长,但在任何计算中都必须提升 – 例如,位置+大小必须是正长。 OS映射确实可能使用long
来进行映射, map
函数(mmap)可能需要映射多于Integer.MAX_VALUE才能保留页面大小但是ByteBuffer只是不能使用它。
整体int
在java的设计中非常深入,并且没有size_t
C类似的类型,使用long
而不是int的质量将阻碍性能。 所以最后:如果你需要比2GB更大的地图,只需要使用多个ByteBuffer。