Java чтение файла с конца

Чтение и запись файлов

В Java есть четыре основных абстрактных класса, реализующих потоки ввода-вывода: InputStream, OutputStream, Reader, Writer. Первые два работают с байтами, вторые – с символами.

Для работы с файлами от этих абстрактных классов созданы соответственно классы FileInputStream, FileOutputStream, FileReader, FileWriter. Они являются адаптерами для объектов класса File к «интерфейсам» InputStream, OutputStream, Reader, Writer, т. е. к их методам.

Скажем несколько слов об адаптере как паттерне, или шаблоне, проектирования. Класс-адаптер A наследуется от интерфейса B, к которому приспосабливается объект другого класса – C. Класс-адаптер A имеет поле типа класса объекта C.

Например, объект File адаптируется к потоку ввода InputStream, т. е. все, что мы хотим получить из File, в конечном итоге мы будем получать из InputStream. Фактически мы работаем с InputStream, через адаптер FileInputStream, который с одной стороны наследуется от InputStream, а с другой – имеет поле, которому присваивается объект File.

Адаптер выполняет работу по получению данных из файла и адаптации их к тому виду, который можно передать в методы InputStream. Класс-адаптер, в данном примере – FileInputStream, переопределяет методы InputStream, добавляя в них свой код.

В основной ветке сначала создается объект, для которого требуется адаптер. Затем создается переменная класса, к которому выполняется адаптация. Этой переменной присваивается объект класса-адаптера, в конструктор которого передается адаптируемый объект.

File file = new File("/home/user/pic.jpg"); InputStream fIn = new FileInputStream(file);

Часто переменную определяют самим классом-адаптером:

FileInputStream fIn = new FileInputStream(file);

В конструктор можно передать строку-адрес. Объект File будет создан внутри адаптера. Пример побайтового копирования файла:

import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class InputOutputStream  public static void main(String[] args) throws IOException  FileInputStream fileIn = new FileInputStream( "src/file/pets.png"); FileOutputStream fileOut = new FileOutputStream( "src/file/pets2.png"); while (fileIn.available() > 0)  int oneByte = fileIn.read(); fileOut.write(oneByte); > fileIn.close(); fileOut.close(); > >

Если используются относительные адреса, они должны начинаться от корня проекта.

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

Метод available() объекта класса FileInputStream возвращает количество непрочитанных байтов. Метод read() читает один байт и расширяет его до типа int. Кроме этого, есть другой метод read(), читающий массив байт в переменную-аргумент и возвращающий количество реально прочитанных байт. Метод write() также позволяет записывать блоками.

byte[] blockBytes = new byte[100]; while (fileIn.available() > 0)  int qtyBytes = fileIn.read(blockBytes); fileOut.write(blockBytes, 0, qtyBytes); >

При чтении конца файла блок может содержать меньше прочитанных байт, чем размерность массива. Поэтому write() позволяет указывать срез массива.

У объектов FileOutputStream имеется метод flush(), который принудительно записывает находящиеся в буфере байты на диск. При вызове close() это происходит автоматически.

С помощью класса PrintStream также можно создать поток вывода в файл. PrintStream является наследником FilterOutputStream, который в свою очередь наследник OutputStream как и FileOutputStream.

import java.io.FileNotFoundException; import java.io.PrintStream; public class PrintStreamTest  public static void main(String[] args) throws FileNotFoundException  PrintStream fileOut = new PrintStream( "src/file/text.txt"); fileOut.println(10.5); fileOut.printf( "%s - %d - %f", "hi", 10, 1.1); fileOut.close(); > >

Функция printf() предназначена для форматированного вывода.

Заметим, переменная System.out является объектом типа PrintStream.

В работе с вводом-выводом также используется другой паттерн проектирования – обертка (wrapper), он же декоратор (decorator). Декоратор расширяет функциональность объекта, а не приспосабливает объект к какому-либо стороннему интерфейсу.

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

В основной ветке создается объект оборачиваемого класса, который передается в конструктор обертки. Внутри класса-обертки есть поле типа декорируемого класса. Этому полю присваивается переданный объект.

BufferedInputStream – класс-обертка для InputStream (наследует через FilterInputStream). В отличие от InputStream класс BufferedInputStream позволяет предварительно читать в буфер порции байт, что уменьшает количество обращений к файлу. Существует также BufferedOutputStream.

import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; public class BufferStream  public static void main(String[] args) throws IOException  FileInputStream fileIn = new FileInputStream("src/file/text.txt"); BufferedInputStream bufIn = new BufferedInputStream(fileIn, 100); int i; while((i = bufIn.read())!= -1) System.out.print((char)i); > > >

Конструктор класса BufferedInputStream принимает объект InputStream или его наследника.

Хотя данные считываются блоками, метод read() извлекает их по одному. Однако в данном случае он будет извлекать их из буфера.

С помощью классов FileReader и FileWriter выполняется ввод-вывод в текстовые файлы.

FileReader reader = new FileReader( "src/file/text.txt"); FileWriter writer = new FileWriter( "src/file/text2.txt"); while (reader.ready())  int c = reader.read(); writer.write(c); > reader.close(); writer.close();

Метод ready() возвращает истину, если остались непрочитанные символы.

Читать и писать можно блоками. Также методу write() можно передать строку:

FileReader reader = new FileReader( "src/file/text.txt"); FileWriter writer = new FileWriter( "src/file/text3.txt"); char[] buff = new char[10]; while (reader.ready())  int qtySymbols = reader.read(buff); writer.write(buff, 0, qtySymbols); > writer.write("Halo"); reader.close(); writer.close();

Рассматривая ввод данных с клавиатуры, мы уже использовали класс BufferedReader, который наследуется от Reader и позволяет читать отдельные строки методом readLine(). Его также можно использовать для построчного чтения файлов:

import java.io.*; public class BufferedReaderTest  public static void main(String[] args) throws IOException  Reader reader = new FileReader( "src/file/text.txt"); BufferedReader buffReader = new BufferedReader(reader); while (buffReader.ready())  System.out.println( buffReader.readLine()); > reader.close(); buffReader.close(); > >

Существует и BufferedWriter.

Программирование на Java. Курс

Источник

Чтение файла с конца

Как заменить чтение строки из консоли на чтение текстового файла?
основное задание: найти частоту суффикса (например, "ing") в текстовом документе. в.

Чтение чисел из файла. Чтение после конца потока невозможно
Товарищи, помогите. В Pascal’e я не силен, так что не бейте меня ногами, но есть задача: написать.

Внешняя сортировка бинарного файла (чтение после конца файла невозможно)
Помогите отладить программу, не вижу, что здесь можно сделать. Похоже, курсор файла где-то в коде.

Вывод из файла в QTableWidget, построчное чтение с конца файла
Привет! Делаю первые шаги в Qt, собственно поэтому без проблем никуда. Моя задача на данный.

Nightwalker,
1. Читаем весь файл в колекцию
2. удаляем первых n и последних n елементов колекции
3. наслаждаемся жизнью

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
public static void main(String[] args){ int dell = 2;// количество нечитаемых строк try { Scanner sc = new Scanner(new File("YourFile.txt")); ArrayListString> read = new ArrayListString>(); while(sc.hasNext()){ read.add(sc.nextLine()); } for(int i = 0; i  dell; i++){ read.remove(0); read.remove(read.size() - 1); } //а дальше с колекцием делаем шо хотим, лепим стринг, записываем, издеваемся. //приятного вам допиливания. } catch (FileNotFoundException ex) { Logger.getLogger(Helper.class.getName()).log(Level.SEVERE, null, ex); } }

Источник

Считывание из файла последней строки

Надо определить последнюю строчку, и взять из нее значение 7348537A889PB5, файл всегда обновляется строки добавляются в конец файла.

Считывание строки из файла до точки
Доброго времени суток 🙂 Вопрос вот в чем, у меня есть файл с текстом. Нужно считывать текст и.

Считывание файла в массив без последней строки
Интересует вопрос, как считывать txt в list БЕЗ последней строки. Мой код который записывает txt.

Считывание последней строки со спец-символом ‘\r’ из текстового файла
Всем привет! Проблема состояла в том, что моя программа неправильно считывала последнее число в.

Функция: сравнение первой строки первого текстового файла и последней строки второго файла
Даны два текстовый файла, состоящие из некоторого количества строк. Написать функцию для сравнения.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
public boolean isValidFile(String filename){ try { FileInputStream fis = new FileInputStream(filename); BufferedReader br = new BufferedReader(new InputStreamReader(fis)); String str1; String str2; while ((str1 = br.readLine()) != null) { str2 = str1; } if (str1.contains("some regexp")){ return true; }else{ return false; } } catch (IOException e) { log.error("IOException occured",e); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
private String getLastLine(final File aFile) { String line = null; String tmp = null; BufferedReader in = null; try { in = new BufferedReader(new FileReader(aFile)); while ((tmp = in.readLine()) != null) { line = tmp; } } catch (FileNotFoundException exception) { LOGGER.error("", exception); } catch (IOException exception) { LOGGER.error("", exception); } finally { IOUtils.closeQuietly(in); } return line; }

На файле в 150Мбайт оба варианта мучаются около секунды, т.к. перебирают весь файл.

На базе RandomAccessFile последняя строка из того же файла получается за пару миллисекунд.

1 2 3 4 5 6 7 8 9 10 11 12 13
private static String ReadLastLine(File file) throws FileNotFoundException, IOException  } return result; }

ЦитатаСообщение от kotelok Посмотреть сообщение

private static String ReadLastLine(File file) throws FileNotFoundException, IOException  RandomAccessFile raf = new RandomAccessFile(file, "r"); String result = null; long startIdx = file.length(); while (result == null  return result; }

Если честно, то я про RandomAccessFile сам узнал только что, попытавшись решить эту задачу.
http://docs.oracle.com/javase/. sFile.html

На практике оказалось, что он реализует достаточно эффективный доступ доступ к файлам по позиции. По крайней мере в сравнении с последовательным перебором всех строк.

По коду — встаём в самый конец файла и пытаемся считать две строки. Если вторая считалась успешно (не null и не пустая), то значит она и есть последняя строка файла. Если не считалась, то повторяем попытку с позиции на единицу меньше, чем конец файла. И так пока не достигнем успеха.

P.S.: но там кривовато получилось. Если в файле всего одна строка или вообще строк нет, то будет беда. Сейчас доработаю.

Источник

Читайте также:  Java get reference to method
Оцените статью