Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> чтение из файла в обратном направлении 
V
    Опции темы
lihusha
Дата 14.6.2009, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 8.6.2008

Репутация: нет
Всего: нет



Здравствуйте.

Подскажите , пожалуйста , как прочитать файл "file.txt" в обратном направлении, т.е. , начиная с конца файла к началу

Спасибо

Это сообщение отредактировал(а) lihusha - 14.6.2009, 11:27
PM MAIL   Вверх
ecologist
Дата 14.6.2009, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 452
Регистрация: 28.2.2007

Репутация: 2
Всего: 9



Смотри RandomAccessFile - перемещайся и читай побайтно.
PM MAIL   Вверх
lihusha
Дата 14.6.2009, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 8.6.2008

Репутация: нет
Всего: нет



примерчика не найдется ?
PM MAIL   Вверх
lihusha
Дата 14.6.2009, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 8.6.2008

Репутация: нет
Всего: нет



Разобрался

Вот примерчик

Код


package phoenix;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;


public class Reverse {

    private File file;
    RandomAccessFile raf;
    FileWriter fw;

    public Reverse(String fileName) throws FileNotFoundException, IOException {
        createFile(fileName);
        raf = new RandomAccessFile(file, "rw");
        fw = new FileWriter(file, true);

    }

    private void createFile(String fileName) throws IOException {
        this.file = new File(fileName);
        file.createNewFile();
    }

    public void reverseReadFromFile() throws FileNotFoundException, IOException {


        String line = "";
        int read = 0;


        long fileLength = file.length();

        for (int i = 0; i <= fileLength; i++) {
            raf.seek(fileLength - i);
            read = raf.read();
            line += (char) read;
        }
        System.out.println("Чтение из файла в обратном направлении");

        System.out.println(line + "\n\n");
    }

    public void readFromFile() throws IOException {


        String output = null;
        System.out.println("Чтение из файла в прямом направлении");
        while ((output = raf.readLine()) != null) {
            System.out.println(output);
        }
        System.out.println("\n\n");
    }

    public void writeToFile(String text) throws IOException {


        fw.write(text);
        fw.flush();
        fw.close();


        System.out.println("Текст '" + text + "' был записан в файл '" + file.getName() + "'\n\n");
    }

    public static void main(String args[]) throws FileNotFoundException, IOException {

        Reverse reverse = new Reverse("test.txt");

        reverse.writeToFile("it is a test text");
        reverse.readFromFile();
        reverse.reverseReadFromFile();

    }
}






Это сообщение отредактировал(а) lihusha - 14.6.2009, 16:26
PM MAIL   Вверх
lihusha
Дата 14.6.2009, 18:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 8.6.2008

Репутация: нет
Всего: нет



мля , как теперь для RandomAccessFile кодировку "UTF-8" выставить ?
PM MAIL   Вверх
AlexeyVorotnikov
Дата 15.6.2009, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 18.6.2007
Где: Москва

Репутация: 10
Всего: 18



Цитата(lihusha @ 14.6.2009,  19:10)
мля , как теперь для RandomAccessFile кодировку "UTF-8" выставить ?

Никак. RandomAccessFile работает с байтами.


--------------------
RTFM!
Три источника и три составные части Java: The Java Language Specification, Java Platform API Specification, The Java Virtual Machine Specification
PM MAIL   Вверх
lihusha
Дата 15.6.2009, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 8.6.2008

Репутация: нет
Всего: нет



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

Может , кто уже сталкивался с такой стеной.
PM MAIL   Вверх
Skynin
Дата 15.6.2009, 21:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 1.7.2007
Где: Харьков

Репутация: 6
Всего: 10



смотрим UTF-8
изучаем java.nio.charset

и выбираем подходы:

1. Читаем побайтно пока не встретим старший утэфовский байт.
Конвертим в символ

2. Читаем побайтно до символа новой строки
Переворачиваем массив
Конвертим в строку

PM MAIL WWW ICQ Skype GTalk YIM MSN   Вверх
lihusha
Дата 15.6.2009, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 8.6.2008

Репутация: нет
Всего: нет



делаю вот так

Код

RandomAccessFile raf = new FandonAccessFile(myFile,"rw");

int read = 0;
String line = null;

for( int i=(int) myFile.length() ; i>=0 ; i--)
{
      raf.seek(i);
      read = raf.read();

       if( (char)read=='\n' )
       {
            line = raf.readLine();
            System.out.println (line);
       }
}




Вот как из строки line получить буквы кириллицы ?
PM MAIL   Вверх
Skynin
Дата 16.6.2009, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 1.7.2007
Где: Харьков

Репутация: 6
Всего: 10



А почему не 
line = raf.readUTF(); Class RandomAccessFile?


PM MAIL WWW ICQ Skype GTalk YIM MSN   Вверх
lihusha
Дата 16.6.2009, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 8.6.2008

Репутация: нет
Всего: нет



генерируется исключение

Код

Exception in thread "main" java.io.EOFException

 

причем , генерируется при любых значениях i в выражении

Код


raf.seek(i);



генерируется даже когда в методе делается вызов
 
Код

raf.readUTF();


без 

Код

raf.seek(i);







Это сообщение отредактировал(а) lihusha - 16.6.2009, 18:12
PM MAIL   Вверх
Skynin
Дата 16.6.2009, 23:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 1.7.2007
Где: Харьков

Репутация: 6
Всего: 10



Цитата(lihusha @ 16.6.2009,  18:06)
генерируется исключение

Потому как в файле - UTF-8?

А если в файле 8битная виндовая кодировка, то сообрази куда вставить, и добавить нехватающего кода:

Код

public CharsetDecoder currCharset;
...
Charset locCharset = Charset.forName("windows-1251");
currCharset = locCharset.newDecoder();


        private String putString(byte[] arrReverse, short realSize) throws CharacterCodingException {
            ByteBuffer lBuff = ByteBuffer.allocate(realSize);
            
            lBuff.put(arrReverse, 0, realSize);
            lBuff.rewind();
    
            return currCharset.decode(lBuff).toString();
        }


    public void reverseReadFromFile() throws FileNotFoundException, IOException {
        System.out.println("Чтение из файла в обратном направлении");

        byte[] arrBt = new byte[999];
        short iarrBt = 0;

        int read = 0;
        long fileLength = file.length();
        for (int i = 1; i <= fileLength; i++) {
            raf.seek(fileLength - i);
            read = raf.read();

    arrBt[iarrBt++] = (byte)read;

    if (read == 10) {
        System.out.println(putString(arrBt,iarrBt));

        iarrBt = 0;
    }
        }
    if (iarrBt > 0)
    System.out.println(putString(arrBt,iarrBt));
        
        System.out.println("\n\n");
    }


PM MAIL WWW ICQ Skype GTalk YIM MSN   Вверх
LSD
Дата 17.6.2009, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



У меня один вопрос: при чем тут Java: Работа с сетью?


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
lihusha
Дата 19.6.2009, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 8.6.2008

Репутация: нет
Всего: нет



Окончательно у меня получился вот такой класс , который может читать построчно , но с конца текстового файла

Код




import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Arrays;
import java.util.LinkedList;


public class ReverseRead {

    private String filePath;
    private File file;
    private RandomAccessFile reader;
    private FileOutputStream fileOS;
    private OutputStreamWriter writer;

    public ReverseRead(String filePath) throws FileNotFoundException, UnsupportedEncodingException {
        this.filePath = filePath;
        file = new File(filePath);
        fileOS = new FileOutputStream(file, true);
        writer = new OutputStreamWriter(fileOS, "UTF-8");
        reader = new RandomAccessFile(file, "rw");
    }

    public void writeText(String text) throws IOException {
        writer.write(text);
        writer.flush();
        writer.close();
    }
//    метод делает следущее

//    -перемещаясь в цикле с конца файла в начало считывает байты,
//     записывая их во временный LinkedList;
//    -когда позиция считывания доходит до начала строки, массив байтов,
//     полученный из LinkedList, реверсируется, декодируется,из него отсекается
//     ненужное содержимое (~ нули в конце строчки) и этот массив передается в
//     конструктор String,строка выводится на консоль.


    public void readFileInReverse() throws IOException {
        LinkedList<Byte> singleStr = new LinkedList<Byte>();
        Byte read;

        for (int i = (int) file.length() - 1; i >= 0; i--) {
            reader.seek(i);
            read = reader.readByte();
            singleStr.addFirst(read);


            if ((char) read.byteValue() == '\n'|| i==0) {
                if((char) read.byteValue() == '\n')singleStr.pollFirst();
                if (singleStr.size() == 0) {
                    continue;
                }
                byte reverseStr[] = new byte[singleStr.size()];

                for (int j = 0; j < singleStr.size(); j++) {
                    reverseStr[j] = singleStr.get(j).byteValue();

                }
                singleStr = new LinkedList<Byte>();
                Charset charset = Charset.forName("UTF-8");
                CharsetDecoder decoder = charset.newDecoder();
                ByteBuffer buf = ByteBuffer.wrap(reverseStr);


                CharBuffer charBuf = decoder.decode(buf);

                char[] msgBytes = Arrays.copyOf(charBuf.array(), charBuf.limit());
                
                String line = new String(msgBytes);
                System.out.println(line);
            }

            

        }
    }
     public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException, IOException {
        ReverseRead reverse = new ReverseRead("rTest.txt");
        reverse.writeText("первая строчка\nвторая строчка\nтретья строчка");
        reverse.readFileInReverse();

    }
}



Это сообщение отредактировал(а) lihusha - 19.6.2009, 19:36
PM MAIL   Вверх
Skynin
Дата 19.6.2009, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 1.7.2007
Где: Харьков

Репутация: 6
Всего: 10



абы работало.

А если бы мне понадобилась такая штука в реальный проект, то я бы:
1. вместо LinkedList<Byte> использовал настоящий массив. Увеличивая его, (и копируя старый в увеличенный)
Почитайте внимательно, как работают дженерик типы в Java для объектов и примитивных типов.

2. избавился от операции "переворота массива", незначительным усложнением алгоритма - записывал бы в массив с конца
2а. или вообще перешел бы на функции работы с файлами из пакета java.nio вместо RandomAccessFile чтобы сразу читать в буфер FileChannel

3. избавился от конструкции:
Код

                char[] msgBytes = Arrays.copyOf(charBuf.array(), charBuf.limit());
                String line = new String(msgBytes);

сведя ее к String line = charBuf.toString();

PM MAIL WWW ICQ Skype GTalk YIM MSN   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0867 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.