2012-03-19 9 views
6

Czy możliwe jest pozycjonowanie kursora na początku określonej linii w pliku poprzez RandomAccessFile?Osiąganie konkretnej linii w pliku przy użyciu RandomAccessFile

Dla np. Chcę zmienić ciąg znaków rozpoczynający się od znaków 10 do 20 w wierszu 111 w pliku. Plik ma zapisy o stałej długości .

Czy można bezpośrednio pozycjonować kursor na początku linii 111 za pomocą opcji RandomAccessFile?

Aktualizacja:

Użyłem następującego kodu. Jednak powracający zerowy.

długość linii wynosi 200 znaków (która wynosi 200 bajtów, jeśli się nie mylę)

File f = new File(myFile); 
RandomAccessFile r = new RandomAccessFile(f,"rw"); 
r.skipBytes(200 * 99); // linesize * (lineNum - 1) 
System.out.println(r.readLine()); 

Gdzie jestem będzie niewłaściwy?

Odpowiedz

3

Nie jestem pewien, ale wydaje się, że RandomAccessFile nie obsługuje takich funkcji. Jak RAF operuje bajtów możemy pominąć określoną ilość bajtów, a jeśli plik ma stałą szerokość linii może to być osiągnięte przez

file.skipBytes(110 * lineSizeInBytes); 

przeciwnym razie trzeba coś takiego:

for (int i = 0; i < 110; i++) file.readLine(); 
String line = file.readLine(); 
+0

Mam stały rekord długości .... pozwól mi sprawdzić, czy to działa .. – Nik

+0

Proszę zobaczyć moje zaktualizowane pytanie .. gdzie jestem źle? – Nik

+0

Każda linia zawiera \ n znak. Tak więc, w rzeczywistości powinieneś pominąć lineCount * (lineSize + 1). – mishadoff

2

Nie można tego zrobić bezpośrednio za pomocą RandomAccessFile. Jest obsługiwany do pracy z plikami binarnymi i pomaga odczytywać i zapisywać takie fragmenty plików w dowolnej wybranej losowej lokalizacji. Właśnie dlatego klasa nazywa się RandomAccessFile.

Ale to nie działa z tekstami, więc nie ma sposobu na rozpoznanie końca wiersza i nie działa w ogóle w liniach.

Tak więc, aby zaimplementować to, co chcesz, powinieneś użyć BufferedReader, czytać wiersz po wierszu i jeśli chcesz zapisać pozycję, w której każda linia jest uruchomiona, dzięki czemu będziesz mógł pominąć wymaganą liczbę bajtów, aby przejść do początku wymaganej linii.

+0

+1, ale OP poniewczasie skomentował, że plik ma zapisy o stałej długości. –

+0

@Andrew Thompson, masz rację. Nie zwracałem uwagi na ten szczegół. – AlexR

+0

Nie, wspomniano tylko * po * odpowiedź została wysłana. Zmieniłem to na pytanie, aby uniknąć dalszego zamieszania. –

1

Aby użyj RandomAccessFile, albo musisz mieć zapisy o stałej długości, albo mieć "wektor dope" przesunięć na początku każdego rekordu (lub np. co 10. rekord). Mogą one być lub nie być odpowiednie dla twojego problemu.

1

Jak stwierdzili niektórzy ludzie, istnieją inne klasy, które zostały specjalnie zaprojektowane do czytania linii tekstu, takich jak BufferedReader. Jednakże, jeśli są wymagane do korzystania z RandomAccessFile, można przeczytać wiersze tekstu, ale trzeba programowo znaleźć gdzie 1 linia kończy i zaczyna się kolejna linia ...

Prostym przykładem może być ...

RandomAccessFile raf = new RandomAccessFile("c:\test.txt","r"); 
String line = ""; 
while (raf.available()){ 
    byte b = raf.read(); 
    if (b == '\n'){ 
    // this is the end of the current line, so prepare to read the next line 
    System.out.println("Read line: " + line); 
    line = ""; 
    } 
    else { 
    line += (char)b; 
    } 
    } 

Daje to podstawowy blok konstrukcyjny dla czytnika, który szuka końca każdej linii.

Jeśli zamierzasz pójść ścieżką używania RandomAccessFile, możesz zacząć od tego schematu, ale musisz mieć świadomość wielu niedogodności i mieć takie ... 1. Używanie Unix i Windows różne markery linii - musisz szukać '\ n', '\ r' i kombinacji obu tych 2.Odczytanie pojedynczego bajtu na raz jest bardzo powolne - powinieneś przeczytać blok bajtów w buforze tablicowym (np. Tablica bajtów [2048]), a następnie iterować po tablicy, uzupełniając tablicę z RandomAccessFile po osiągnięciu końca tablica buforów. 3. Jeśli masz do czynienia ze znakami Unicode, musisz czytać i przetwarzać 2 bajty na raz, zamiast pojedynczych bajtów.

RandomAccessFile jest bardzo potężny, ale jeśli możesz użyć czegoś takiego jak BufferedReader, prawdopodobnie lepiej byłoby go użyć zamiast tego, ponieważ automatycznie zajmuje się tymi wszystkimi problemami.

Powiązane problemy