Почему FileChannel.map подходит для Integer.MAX_VALUE данных?
Я получаю следующее исключение при использовании 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 показывает, что метод map (..) в FileChannelImpl
принимает size
типа long
как входной. Но внутри тела он сравнивает его с 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-битной JRE на 64-битной Windows-2k8
Ответы
Ответ 1
Это не ошибка конкретной реализации. Размер определен в FileChannel.map как долго, но...
size - размер области для отображения; должен быть неотрицательным и не превосходить Integer.MAX_VALUE
Все совместимые реализации JVM будут такими. Я подозреваю, что причина - это комбинация истории (кому нужно было бы получить доступ к файлу размером более 2 ГБ?) И попытаться продвинуть вперед в более поздних версиях Java (будет проще разрешить значения, превышающие Integer.MAX
, чем это будет изменить тип данных с int
на long
.)
Многие люди находят это основанное на основах мышление в Java API относительно чего-либо Файла, очень смешающего и недальновидного. Но помните, Java начал разработку в 1995 году! Я уверен, что 2GB в то время представляло собой относительно безопасную ценность.
Ответ 2
Вместимость 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 приведет к снижению производительности. Итак, в конце: если вам нужны большие карты, чем 2 ГБ, просто используйте больше, чем один ByteBuffer.