При отладке проблемы на работе я заметил, что попытка использовать MappedByteBuffer после открытия FileOutputStream для сопоставленных файл (файл, из которого был создан MappedByteBuffer по вызову FileChannel.map()), последовательно вызывает следующее исключение:Чтение из java.nio.MappedByteBuffer, когда FileOutputStream открыто для сопоставленного файла, вызывает ошибку «небезопасного доступа к памяти»
«Исключение в потоке» main «java.lang.InternalError: произошла ошибка в небезопасная операция доступа к памяти ".
Вот небольшой пример кода, я бросил вместе, что последовательно вызывает исключение:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class SomeClass {
// make sure the test file is at least this size, or you'll get a "cannot
// extend file to required size" exception when creating the buffer
private static int bufferSize = 10;
public static void main(String[] args) throws Exception {
File file = new File("/tmp/someFile");
FileInputStream fis = new FileInputStream(file);
ByteBuffer bb = getByteBuffer(fis);
// If you comment this out, the error goes away.
new FileOutputStream(file);
bb.get();
}
private static ByteBuffer getByteBuffer(FileInputStream fis) throws Exception {
return fis.getChannel().map(FileChannel.MapMode.READ_ONLY,
fis.getChannel().position(), bufferSize);
}
}
Приведенный выше код последовательно вызывает вышеупомянутое исключение быть выброшен. Ошибка происходит в команде «bb.get()» и не происходит, если я прокомментирую код, который открывает FileOutputStream.
Мне кажется, что ошибка происходит из-за того, что ByteBuffer, который я вызываю .get() включен, сопоставляется памяти с тем же файлом, который я передал в FileOutputStream. Я предполагаю, что существует некоторая внутренняя защита, которая предотвращает чтение файлов с отображением памяти, если файл открыт, но я не могу понять, в чем причина этого.
Что является особенностью памяти ByteBuffers с отображением памяти, которая препятствует разрешению операции чтения при открытии файла FileOutputStream в файле? Мне очень интересно понять внутренности этого исключения. То, что меня тоже озадачивает, заключается в том, что, похоже, не существует аналогичной проблемы с открытием FileInputStream и чтением из него, когда FileOutputStream открыт для одного и того же файла, даже если это должно быть существенно функционально схожим (чтение из файла, который уже открыт для записи).
Вы абсолютно правы - это определенно то, что происходит. Я сделал еще один быстрый тест, в котором я передал флаг «append» в FileOutputStream, и проблема больше не возникает. –