в Java, как эффективно читать х строк из файла, закрыть его, а затем открыть его снова, начиная со строки х и продолжить чтение - PullRequest
2 голосов
/ 03 ноября 2010

BufferedReader имеет простые методы для чтения файла построчно.Но, похоже, нет никакого способа отслеживать, где вы находитесь, поэтому вы можете вернуться к этому месту позже.FileInputStream имеет файл getChannel (), который возвращает FileChannel, который может сообщить вам текущую позицию в потоке.Поэтому, если вы даете BufferedReader FileInputStream для чтения, вы можете узнать, где BufferedReader прекратил чтение в FileInputStream, и вы также можете установить FileInputStream на эту позицию, прежде чем передать его буферизованному читателю.

Проблема в том, что BufferedReader прочитал вперед в файле.Таким образом, позиция FileInputStream не совпадает с позицией в BufferedReader.Возможно, вы прочитали 20 строк из BufferedReader, но BufferedReader, возможно, прочитал 30 из FileInputStream.Если позже вы снова откроете файл, основываясь на позиции в FileInputStream, вы пропустите эти промежуточные 10 строк.

Я мог бы читать символ за символом из InputStream, но, похоже, есть лучший способ...

Ответы [ 3 ]

1 голос
/ 03 ноября 2010

Это чрезвычайно сложная проблема для решения с использованием существующих классов Java. По одной причине вы проигнорировали тот факт, что вы не можете фактически передать InputStream в BufferedReader, вам нужно передать Reader.

Файлы работают в байтах, а читатели - с символами. Поскольку любой данный символ может занимать произвольное количество байтов в произвольном наборе символов, вам нужно будет записать, сколько байтов каждого символа потребовалось, чтобы иметь возможность вычислить количество байтов, которое определенное количество символы представлены в файле.

Если вы готовы пойти на очень хрупкий подход, вы можете предположить, что каждый байт в вашем файле представляет символ (например, ASCII) и что каждая строка заканчивается "\n". Тогда нужно просто записать, сколько символов вы прочитали. Примерно так:

public class CountingBufferedReader extends BufferedReader {
     private int position = 0;
     public String readLine() {
        String line = super.readLine();
        position += line.length() + 1;
        return line;
     }

     public int getPosition() {
         return position;
     }
}

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

0 голосов
/ 04 ноября 2010

Используйте класс java.io.LineNumberReader.Это говорит вам, на какой линии вы находитесь в данный момент.В следующий раз просто прочитайте столько строк.Это делает вашу проблему O (N ** X), ​​где X - это количество раз, которое вы читали файл, но тогда почему вы все равно читаете только часть файла?

0 голосов
/ 03 ноября 2010

Возможно, он не ответит полностью на ваш вопрос, но Apache IOUtils будет считывать поток в список http://commons.apache.org/io/api-1.4/org/apache/commons/io/IOUtils.html#readLines%28java.io.InputStream%29

Затем вы можете получить прямой доступ к любой строке в списке (поток будет закрыт) * ​​1004 *

из их документов:

public static List readLines(InputStream input)
                      throws IOException

    Get the contents of an InputStream as a list of Strings, one entry per line, using the default character encoding of the platform.

    This method buffers the input internally, so there is no need to use a BufferedInputStream.

    Parameters:
        input - the InputStream to read from, not null 
    Returns:
        the list of Strings, never null 
    Throws:
        NullPointerException - if the input is null 
        IOException - if an I/O error occurs
    Since:
        Commons IO 1.1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...