Загрузить текстовый файл в память на Java - PullRequest
3 голосов
/ 14 декабря 2011

У меня есть файл wiki.txt, и его размер составляет 50 МБ.

  1. Мне нужно сделать несколько вещей с файлом, и я подумал, что лучший способ с точки зрения производительности - этозагрузить файл в память, это правильно?

  2. Это код, который я написал:

    File file = new File("wiki.txt");
    FileInputStream fileInputStream = new FileInputStream(file);
    FileChannel fileChannel = fileInputStream.getChannel();
    MappedByteBuffer mapByteBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, file.length());
    System.out.println((char)mapByteBuffer.get());
    

Я получаю сообщение об ошибкеэтот код: mapByteBuffer.get().Я попробовал функцию get () с несколькими опциями, но во всех них я получаю сообщение об ошибке и даже не получаю сообщение об ошибке. E.getMessage () Я только что получил значение null.

Еще одна важная вещь, которую стоит отметить, мой текстФайл содержит английские слова и действия, которые мне нужно сделать, это поиск, если в этом текстовом файле есть выражение.

Спасибо.

Ответы [ 4 ]

3 голосов
/ 14 декабря 2011

Я бы предложил использовать MemoryMappedFile, чтобы читать файл непосредственно с диска, а не загружать его в память.

RandomAccessFile file = new RandomAccessFile("wiki.txt", "r");
FileChannel channel = file.getChannel();
MappedByteBuffer buf = channel.map(FileChannel.MapMode.READ_WRITE, 0, 1024*50);

И тогда вы можете читать буфер как обычно.

2 голосов
/ 14 декабря 2011

Важно прочитать всю ошибку, а не только сообщение.Часто реальная информация содержится в имени исключения, а не в тексте, связанном с ним.

Вы получите сообщение об ошибке, если файл пуст, так как нет первого байта.

Примечание.Использует предполагает ASCII 7-битные символы.Если вы хотите использовать символы ISO-8859-1, вы можете использовать (char) (byteBuffer.get() & 0xFF)

Однако, если у вас есть текст плана, вы можете обнаружить, что использование строк проще и не намного медленнее.Например, вы можете прочитать файл размером 50 МБ в виде текста менее чем за секунду.Я бы использовал файл с отображением памяти, только если он слишком длинный.

2 голосов
/ 14 декабря 2011

Мои ответы по пункту (1):

Это зависит от того, что вы хотите сделать с файлом.Если ваша обработка не включает в себя операцию перемотки (смотря, что было прочитано за / до), лучше просто прочитать как поток и обработать его за один раз (вместо загрузки всего в память).вам нужен произвольный доступ ко всему файлу, вы также можете быть заинтересованы в выполнении операции с блочным файлом, потому что ваше решение может не масштабироваться при изменении размера файла на больший. RandomAccessFile , если вы используете Java 1.4 или выше.Для произвольного доступа операционная система обычно обрабатывает кеширование файлового буфера достаточно хорошо, вам не нужно обрабатывать себя.

1 голос
/ 14 декабря 2011

Я бы предложил использовать BufferedReader. Это намного быстрее и требует относительно меньше ресурсов. Сначала прочитайте количество строк:

InputStream is = new BufferedInputStream(new FileInputStream(filename));
byte[] chars = new byte[1024];
int numberOfChars = 0;
while ((numberOfChars = is.read(chars)) != -1) 
{
    for (int i = 0; i < numberOfChars; ++i) 
    {
        if (chars[i] == '\n' && numberOfChars - i != 1)
        {
            ++count;
        }           
    }
}
count++
return count; // number of lines

Затем прочитайте строки:

BufferedReader in = new BufferedReader(new FileReader(fileName));
for (int i = 0; i < endLine; i++) 
{
    String oneLine = in.readLine();
}

В этих строках вы можете даже искать то, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...