Почему FileChannel.map принимает данные Integer.MAX_VALUE? - PullRequest
12 голосов
/ 10 ноября 2011

Я получаю следующее исключение при использовании 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 принимает 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

Ответы [ 2 ]

6 голосов
/ 12 февраля 2012

Это не специфичная для реализации ошибка. Размер определяется в FileChannel.map как long, но ...

размер - размер отображаемой области; должно быть неотрицательным и не более Integer.MAX_VALUE

Все совместимые реализации JVM будут такими. Я подозреваю, что причина заключается в сочетании истории (кому потребуется доступ к файлу размером более 2 ГБ?) И попытке продвинуться вперед в более поздних версиях Java (будет проще разрешить значения, превышающие Integer.MAX, чем это будет чтобы изменить тип данных с int на long.)

Многие люди находят это интуитивное мышление в Java API относительно чего-либо очень смущающим и недальновидным. Но помните, Java начала разработку в 1995 году! Я уверен, что 2 ГБ казались относительно безопасным значением в то время.

3 голосов
/ 11 июня 2012

Емкость 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, снизит производительность.Итак, в конце: если вам нужны карты большего размера, чем 2 ГБ, просто используйте более одного ByteBuffer.

...