Почему 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.