LXF86:Java

Материал из Linuxformat.

(Различия между версиями)
Перейти к: навигация, поиск
(Запись данных)
(Свободный доступ)
Строка 105: Строка 105:
=== Свободный доступ ===
=== Свободный доступ ===
 +
В представленных ранее примерах доступ к данным осуществляется последовательно, что не всегда удобно (хотя в большинстве случаев именно такой доступ и используется). Для осуществления чтения и записи данных из файла в произвольном порядке существует специальный класс RandomAccessFile, экземпляр которого создается следующим образом:
 +
<source lang = "java">
 +
RandomAccessFile raf = new RandomAccessFile(pathToFile, mode);
 +
</source>
 +
При этом pathToFile — путь до файла, а mode — режим работы. mode может принимать значения: r (только чтение), rw (чтение-запись), rws (чтение-запись с синхронным сохранением содержимого и метаданных), rwd (чтение-запись с синхронным сохранением содержимого файла). К сожалению, кодировку указать нельзя. Огромным преимуществом подхода является то, что с помощью метода getFilePointer() можно узнать текущее месторасположение указателя, а с помощью метода seek() можно передвинуть указатель в необходимое место в файле. Я предпочитаю не использовать данный класс — считайте это личным предубеждением.
=== Протоколирование работы программы ===
=== Протоколирование работы программы ===

Версия 10:00, 13 марта 2008

Содержание

Хранение данных

ЧАСТЬ 3: Даже самой замечательной программе надо откуда-то черпать данные для своей работы. Данные, как известно, хранятся в файлах. Тему продолжает Антон Черноусов.

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

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

Файлы — потоки

Сказочное королевство под руководством царевны Несмеяны (так как cупруг практически всегда отсутствовал), благодаря талантам и приобретенным навыкам, стало разрастаться, и результаты полюдья просто-напросто перестали помещаться в семейный чулан. Чтобы накапливать и хранить богатства, потребовались дополнительные помещения, роль которых для нас привычно играют файлы.

Отношение к файлам в Java достаточно непростое: если рассматривать файл как устройство для ввода/вывода информации — с этой точ ки зрения он подобен блоку памяти или экрану, интерфейс доступа к которому унифицирован: это поток. Но несмотря на унифицированный интерфейс, существует большое количество классов сходной функциональности, в которых легко запутаться.

Поток можно представить в виде ленточного конвейера с последовательным размещением или извлечением данных, при использовании которого задача программиста сводиться к осуществлению операций «поместить/читать» данные, а остальные детали реализации скрыты от него.

Чтение данных

Разнообразие классов для работы с файлами позволяет выбрать для себя ту связку, которая больше нравится. Лично я для чтения данных использую BufferedReader, InputStreamReader и FileInputStream. Собственно взаимодействие этих классов для программиста заканчивается в момент создания экземпляра BufferedReader, что делается следующим образом:

BufferedReader br = null;
br = new BufferedReader(new InputStreamReader(new FileInputStream(pathToFile), encoding));

В процессе создания участвуют строковые переменные, содержащие путь к файлу и кодировку, в которой производится считывание данных: pathToFile и encoding. В классах, работающих с файлами, считается обязательным создавать переменную для кодировки по умолчанию:

protected static String DEFAULT_ENCODING = "UTF-8";

Любой текстовый файл можно представить себе в виде набора строк, поэтому давайте реализуем метод для считывания содержимого файла в массив String[]. Далее представлен метод rippedCurrentFile(path ToFile, encoding) класса FileRipper, который извлекает данные из файла с помощью метода readLine() экземпляра класса BufferedReader:

protected boolean rippedCurrentFile(String pathToFile, String encoding) {
  // connecting to file
  BufferedReader br = null;
  try {
    br = new BufferedReader(new InputStreamReader(new FileInputStream(pathToFile),encoding));
  } 
  catch (UnsupportedEncodingException e) {
    this.error = FILE_ERROR_UNSUPPORTED_ENCODING; return false;
  } 
  catch (FileNotFoundException e) {
    this.error = FILE_ERROR_NO_FILE; return false;
  }
  // ripping the file
  String str = null;
  ArrayList allStrings = new ArrayList();
  try {
    while (!(str = br.readLine()).equals(null)) { allStrings.add(str); }
  } 
  catch (IOException e) {
    this.error = FILE_ERROR_IO_READ; return false;
  } 
  catch (NullPointerException e) {
    this.error = FILE_ERROR_END_OF_FILE;
  }
  // free the resources
  try {
    br.close();
  } 
  catch (IOException e) {
    this.error = FILE_ERROR_IO_CLOSE; return false;
  }
  this.allStrings = (String[]) allStrings.toArray(new String[0]); 
  return true;
}

Полный код примера, в том числе код класса ConsoleToFileRipper, применяющий экземпляр класса FileRipper для извлечения данных из файла, можно найти на диске в каталоге examples 1.

Запись данных

Процесс записи данных в файл хоть и отличается от чтения, но тоже достаточно похож на организацию конвейера. Для записи я обычно использую связку BufferedWriter, OutputStreamWriter, FileOutputStream.

BufferedWriter out;
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(pathToFile), encoding));

Для освобождения ресурсов, которые используют экземпляры классов BufferedReader и BufferedWriter, необходимо вызвать метод close().

Далее приведу простой пример метода, который записывает строковый массив в файл (полный код метода расположен на диске в директории examples 2):

public boolean createCurrentFile(String pathToFile, String[] allStrings, String encoding){
  try {
    BufferedWriter out;
    out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(pathToFile), encoding));
    for (int i = 0; i < allStrings.length; i++) {
      out.write(allStrings[i]); out.write(‘\n’);
    }
    out.close();
  } 
  catch (IOException e) {
    e.printStackTrace(); 
    return false;
  }
  return true;
}

Свободный доступ

В представленных ранее примерах доступ к данным осуществляется последовательно, что не всегда удобно (хотя в большинстве случаев именно такой доступ и используется). Для осуществления чтения и записи данных из файла в произвольном порядке существует специальный класс RandomAccessFile, экземпляр которого создается следующим образом:

RandomAccessFile raf = new RandomAccessFile(pathToFile, mode);

При этом pathToFile — путь до файла, а mode — режим работы. mode может принимать значения: r (только чтение), rw (чтение-запись), rws (чтение-запись с синхронным сохранением содержимого и метаданных), rwd (чтение-запись с синхронным сохранением содержимого файла). К сожалению, кодировку указать нельзя. Огромным преимуществом подхода является то, что с помощью метода getFilePointer() можно узнать текущее месторасположение указателя, а с помощью метода seek() можно передвинуть указатель в необходимое место в файле. Я предпочитаю не использовать данный класс — считайте это личным предубеждением.

Протоколирование работы программы

Документы XML

Создание XML-документа

Сохранение XML-документа

Загрузка XML-документа

Извлечение данных из XML-документа

Личные инструменты
  • Купить электронную версию
  • Подписаться на бумажную версию