Занятие №4

Работа с файловой системой. Потоки ввода/вывода. Обработка исключений

Владимир

Лебедко

Обо мне

Лебедко Владимир

старший разработчик

компания "Сибирские Интеграционные Системы"

Опыт работы:

  • с 2009 года 

Технологии, с которыми работал:

  • Базы данных: PostgreSQL, Intersystem Cache
  • Бэкэнд: Cache(COS), Java (Spring, SpringData, Hibernate,Apache Camel, ActiveMQ), C#
  • Фронтэнд: ActionScript (Flex), JavaScript

Файловая система

Для чего ?

  • Ввод информации
    • Пользовательские данные
    • Файлы параметров
  • Вывод результата
    • Результат обработки
    • Промежуточная информация

File

File - методы

  • boolean exists() - Существует?
  • String getName() - Название
  • String getPath() - Путь к файлу

  • String getAbsolutePath() - Абсолютный путь

  • String getCanonicalPath() - Абсолютный канонический путь

  • boolean canRead() - Доступ на чтение (атрибут)

  • boolean canWrite() - Доступ на запись​ (атрибут)

File -> Общие

  • boolean isDirectory() - Это директория ?

  • boolean isFile() - Это файл?

  • File getParent() - родительский каталог

  • File[] listFiles(FileFilter filter) - список файлов по фильтру
  • boolean mkdir() - создание каталога

  • boolean mkdirs() - создание каталога с подкаталогами

File -> Каталог

File -> Файл

  • boolean length() - размер

Path API

  • Path resolve(String) - подкаталог 

  • Path resolve(Path) - подкаталог 

  • File toFile() - экземпляр File

  • Path subpath() - часть пути

  • Path getParent() - родитель

Объектное представление пути файловой системы

Path это интерфейс. А как тогда создать экземпляр ?

Paths - Фабрика

Paths.get("C:/temp1/temp2/someFile.txt");

Paths.get("C:/", "temp1", "temp2", "someFile.txt");

Идентично

Почему не просто new PathSomeImpl() ?

Paths.get()

public static Path get(String first, String... more) {
   return FileSystems.getDefault().getPath(first, more);
}

Платформо-зависимая имплементация 

  • WindowsPath - Windows
    
  • UnixPath - Linux

Потоки

Имплементации

Input/Output Stream 

  • FileInputStream / FileOutputStream - Потоки для работы с файлами
  • ByteArrayInputStream / ByteArrayOutpuStream - Потоки для работы с байтовыми массивами

Диаграмма классов Stream

Читаем файл

File inputFile = Paths.get(".")
                  .resolve("inputAuthors.csv")
                        .toFile();

FileInputStream fis = new FileInputStream(inputFile);

int read = 0;
while ((read = fis.read()) != -1) {
    System.out.print((char) read);
}
fis.close();

Пишем файл

File copyFile = tempFolder.
                           newFile("copyAuthors.csv");

File inputAuthorsFile =
            Paths.get(".").resolve("inputAuthors.csv").toFile();
FileInputStream fis = new FileInputStream(inputAuthorsFile);
FileOutputStream fos = new FileOutputStream(copyFile);

int read = 0;
byte[] buffer = new byte[4096];
while ((read = fis.read(buffer)) != -1) {
    fos.write(buffer, 0, read);
}

fis.close();
fos.close();

А как работать с текстовыми файлами?

Символьные потоки

Reader / Writer

Читаем текстовый файл

File file = Paths.get(".").resolve("inputAuthors.csv").toFile();
    
FileInputStream fis = new FileInputStream(file);

InputStreamReader reader = 
            new InputStreamReader(fis,StandardCharsets.UTF_8);

BufferedReader lineReader = new BufferedReader(reader);

String readLine = null;
while ((readLine = lineReader.readLine()) != null)
{
    System.out.println(readLine);
}

lineReader.close();

А можно еще проще? 

Можно! java.util.Scanner

 

Path file =
        Paths.get(FOLDER)
                .resolve("inputAuthors.csv");

Scanner scanner = new Scanner(file, 
                           String.valueOf(StandardCharsets.UTF_8));

while (scanner.hasNext())
{
    System.out.println(scanner.nextLine());
}

scanner.close();

А запись ?

java.io.Files

File writeFile = tempFolder.newFile("somedata.txt");

BufferedWriter buffWriter 
            = Files.newBufferedWriter(writeFile.toPath(),
                            StandardCharsets.UTF_8,
                                StandardOpenOption.APPEND);
List<String> stringArray = Arrays.asList("Строка номер 1",
                                         "Строка номер 2");
for (String itemString :
        stringArray) {
    buffWriter.write(itemString);
    buffWriter.newLine();
}
buffWriter.close();

А если на write произойдет ошибка?

метод не выполнится

Как этого избежать?

buffWriter.close();

Обработка исключений

обработчик

Stacktrace

Стэк

Как поймать?

try {
    BufferedWriter buffWriter 
           = Files.newBufferedWriter(writeFile.toPath());
    //Блок кода бросающий исключение IOException
    //Например кончилось место на диске
    buffWriter.write("someText");

    buffWriter.close();
}
catch (IOException e) {
    buffWriter.close();
}

Try - Catch

А если другое исключение?

ByteArrayInputStream bais = null;
try {
    byte[] bytes = new byte[100];
    bais = new ByteArrayInputStream(bytes);

    throw new IllegalArgumentException();
}
finally {
    System.out.println("Finaly execute");
    if(bais!=null) {
        bais.close();
        System.out.println("Stream closed");
    }
}

Finally -  выполнится в любом случае

А можно проще ?

try-with-resources

Освобождаем ресурсы правильно!

Вернемся к примеру с чтением файла


try (BufferedReader lineReader 
                        = new BufferedReader(reader)) {

    String readLine = null;
    while ((readLine = lineReader.readLine()) != null) {
        System.out.println(readLine);
    }
}

Все просто.

Интерфейс AutoCloseable

  • Имплементируем
  • Переопределяем метод close()
  • Используем в блоке try {}

Типы исключений

Полезные ссылки

Полезные библиотеки

Домашнее задание

CSVAdapter<Author> authorCsvAdapter = 
      new CSVAdapterImpl<Author>(Author.class,fileReader,fileWriter);

Author author = authorCsvAdapter.read(0);
assertEquals("Лев Николаевич Толстой",author.getName());
assertEquals("Ясная Поляна",author.getBirthPlace());

Author authorNew = new Author();
authorNew.setName("Некоторый Автор");
authorNew.setName("Некоторый Город");

int rowIndex = authorCsvAdapter.append(authorNew);

Author authorNewOpened = authorCsvAdapter.read(rowIndex);

assertEquals("Некоторый Автор",author.getName());
assertEquals("Некоторый Город",author.getBirthPlace());
Made with Slides.com