2013-09-21 1 views
0

У меня есть текстовый файл, содержащий около 1 миллиона строк информации. Я ищу способ перейти к определенной строке, учитывая, что я знаю, какую строку я хочу, и все строки имеют одинаковую длину.Перейти к определенной строке в .txt файле, где все строки имеют одинаковую длину в Java

Я читал, что это возможно, без необходимости читать каждую строку, учитывая, что все линии равны. Если да, может ли кто-нибудь предоставить пример кода, как мне это сделать? Или мне лучше просто читать каждую строку и зацикливать ее?

+0

Если вы знаете длину строки в байтах, вы можете использовать 'SeekableByteChannel': http://docs.oracle.com/javase/tutorial/essential/io/ rafs.html –

ответ

0

Вы ищете это:

String line = FileUtils.readLines(file).get(lineNumber); 

или вы можете попробовать использовать итератор, как это: -

LineIterator l= IOUtils.lineIterator(new BufferedReader(new FileReader("file.txt"))); 
for (int lineNumber = 0; l.hasNext(); lineNumber++) { 
    String line = (String) l.next(); 
    if (lineNumber == desiredLineNumber) { 
     return line; 
    } 
} 

EDIT: -

От here: -

int sizeofrecordinbytes = 290; 
// for this example this is 1 based, not zero based 
int recordIWantToStartAt = 12400; 
int totalRecordsIWant = 1000; 

File myfile = new File("someGiantFile.txt"); 


// where to seek to 
long seekToByte = (recordIWantToStartAt == 1 ? 0 : ((recordIWantToStartAt-1) * sizeofrecordinbytes)); 

// byte the reader will jump to once we know where to go 
long startAtByte = 0; 

// seek to that position using a RandomAccessFile 
try { 
     // NOTE since we are using fixed length records, you could actually skip this 
     // and just use our seekToByte as the value for the BufferedReader.skip() call below 

    RandomAccessFile rand = new RandomAccessFile(myfile,"r"); 
    rand.seek(seekToByte); 
    startAtByte = rand.getFilePointer(); 
    rand.close(); 

} catch(IOException e) { 
    // do something 
} 

// Do it using the BufferedReader 
BufferedReader reader = null; 
try { 
    // lets fire up a buffered reader and skip right to that spot. 
    reader = new BufferedReader(new FileReader(myfile)); 
    reader.skip(startAtByte); 

    String line; 
    long totalRead = 0; 
    char[] buffer = new char[sizeofrecordinbytes]; 
    while(totalRead < totalRecordsIWant && (-1 != reader.read(buffer, 0, sizeofrecordinbytes))) { 
     System.out.println(new String(buffer)); 
     totalRead++; 
    } 
} catch(Exception e) { 
    // handle this 

} finally { 
    if (reader != null) { 
     try {reader.close();} catch(Exception ignore) {} 
    } 
} 
+0

Это все еще читает каждую строку, хотя –

+0

@JeroenVannevel: - Да, но я дал первое решение, если OP знает номера строк, тогда мы можем использовать String line = FileUtils.readLines (файл) .get (lineNumber); (Поправьте меня, если я ошибаюсь !!) –

+1

Я согласен, что это удобный метод, но он все равно будет читать каждую строку файла (что противоречит запросам OP). –

1

I gue сс вы ищете случайный доступ к файлам

File file = ...; 
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r"); 
int lineNumber = ...; // first line number is 0 
int lineWidth = ...; // your fixed line width 
long beginIndexOfLine = lineWidth * lineNumber; 
randomAccessFile.seek(beginIndexOfLine); 

byte[] line = new byte[lineWidth]; 
randomAccessFile.read(line); 
+0

Указатель на поиск в 'RandomAccessFile = lineWidth * lineNumber', только если строки (текст) являются однобайтными символами, в противном случае нам приходится учитывать кодировку символов в преобразовании char-> bytes. –

+0

Спасибо, да, я искал что-то вроде этого. Но как проверить ширину линии? Это зависит от количества символов или байтов на строку? Я использую кодировку ASCII. –

+0

@ChrystleSoh, поскольку все ваши строки имеют одинаковую ширину, просто прочитайте первую строку (используя, например, «BufferedReader») и преобразуйте в длину байта '(string.getBytes (« кодировка символов »). Length)' и сохраните его как константу где-то. –

Смежные вопросы