Понедельник, 06.01.2025
Приветствую Вас Гость

Шенденков С.В.
(Zmey)

Если Вы хотите вернуться на предыдущий язык, то нажмите кнопку Назад в Вашем браузере
Выбрать язык / Choose language:
Ukranian
English
French
German
Japanese
Italian
Portuguese
Spanish
Danish
Chinese
Korean
Arabic
Czech
Estonian
Belarusian
Latvian
Greek
Finnish
Serbian
Bulgarian
Turkish
Главная | Регистрация | Вход | RSS

Работа с файлами на Java

А сейчас давайте научимся работать с файлами.
Например, создадим программу, которая копирует содержимое одного файла в другой. Это нам поможет разобраться как читать данные из файла и как их записывать в файл. Для этого создайте новый проект с основным классом под названием SecondFile, код которого приведён ниже:

package zmey_console_files;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Класс копирования файлов
 *
 * @author Zmey
 * @author http://shendenkov.at.ua
 */
public class SecondFile {

    // Файлы по умолчанию
    private String fileName1 = "E:\\first.txt";
    private String fileName2 = "E:\\second.txt";
    // Буфер данных файла
    private byte[] buffer = null;

    public SecondFile(String file1, String file2) {
        // Если имя исходного файла было введено, то используем его
        if (file1 != null) {
            this.fileName1 = file1;
        }
        // Если имя получаемого файла было введено, то используем его
        if (file2 != null) {
            this.fileName2 = file2;
        }
        // Счётчик
        int i = 0;
        int bytesAvailable = 0;
        // Потоки
        FileInputStream inFile = null;
        DataInputStream inData = null;
        FileOutputStream outFile = null;
        DataOutputStream outData = null;
        try {
            // Открываем входящий файловый поток из файла
            inFile = new FileInputStream(fileName1);
            // Открываем входящий поток данных из файлового потока
            inData = new DataInputStream(inFile);
        } catch (FileNotFoundException e) {
            System.out.println("Can not find file: " + fileName1);
        } catch (IOException e) {
            System.out.println("Input/Output error: " + e.toString());
        }
        try {
            System.out.println("File " + fileName1 
                    + " is open for read");
            // Определяем сколько доступно байт в потоке
            bytesAvailable = inFile.available();
            buffer = new byte[bytesAvailable];
            System.out.println("Ready for reading " + bytesAvailable 
                    + " bytes");
            for (; i < bytesAvailable; i++) {
                // Читаем очередной байт из потока
                buffer[i] = inData.readByte();
            }
        } catch (FileNotFoundException e) {
            System.out.println("Can not read file: " + fileName1);
        } catch (IOException e) {
            System.out.println("Input/Output error: " + e.toString());
        } finally {
            try {
                // Закрываем входящие потоки
                if (inData != null) {
                    inData.close();
                }
                if (inFile != null) {
                    inFile.close();
                }
                System.out.println("Input stream is close");
            } catch (IOException e) {
            }
        }
        System.out.println("Readed " + i + " bytes");
        // Если буфер заполнен данными из файла
        if (buffer != null) {
            // Здесь можно было бы обработать данные, полученные из
            //входящего файла. Например, они могли бы быть преобразованы
            //в другой формат.
            try {
                // Открываем исходящий файловый поток из файла
                outFile = new FileOutputStream(fileName2);
                // Открываем исходящий поток данных из файлового потока
                outData = new DataOutputStream(outFile);
                System.out.println("File " + fileName2 
                        + " is open for write");
                System.out.println("Ready for writing " + buffer.length 
                        + " bytes");
                for (i = 0; i < buffer.length; i++) {
                    // Пишем очередной байт в поток
                    outData.writeByte(buffer[i]);
                }
            } catch (FileNotFoundException e) {
                System.out.println("Can not write to file: " 
                        + fileName2);
            } catch (IOException e) {
                System.out.println("Input/Output error: " 
                        + e.toString());
            } finally {
                try {
                    // Закрываем исходящие потоки
                    if (outData != null) {
                        outData.close();
                    }
                    if (outFile != null) {
                        outFile.close();
                    }
                    System.out.println("Output stream is close");
                } catch (IOException e) {
                }
            }
            System.out.println("Writed " + i + " bytes");
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // Если введены оба параметра
        if (args.length == 2) {
            new SecondFile(args[0], args[1]);
            return;
        }
        // Если введён только один параметр
        if (args.length == 1) {
            new SecondFile(args[0], null);
            return;
        }
        new SecondFile(null, null);
    }
}

Давайте разберёмся с новыми для нас конструкциями try - catch, исключениями и потоками.

Конструкция try - catch обеспечивает стабильность программам написанным на языке Java. В блоке try происходит выполнения кода, который может вызвать ошибку (исключительную ситуацию или просто исключение). За ним могут идти несколько блоков catch, каждый из которых выполняет обработку одного из видов исключений. То есть, если в блоке try возникает ошибка, то начинается выполнение соответствующего блока catch. Если же ошибок не возникает, то catch пропускается. Если есть блок try, то должен быть как минимум один блок catch. Также существует блок finally. Это не обязательный блок для этой конструкции. Если этот блок присутствует, то код находящийся в нём будет выполнен независимо от того, произошла ли в блоке try ошибка или нет.

Исключение, как уже было написано выше, это исключительная ситуация, которая может возникнуть во время выполнения программы. Некоторые методы описаны таким образом, что сами не обрабатывают исключительные ситуации, а просто передают её на более высокий уровень программы. То есть, на тот уровень, который вызывает такой метод. Таким образом программист обязан обработать ошибку на текущем уровне или передать на следующий уровень иначе программа не будет скомпилирована. Суперкласс ошибки это класс Exception. От него унаследованы множество классов ошибок, которые уточняют какая именно ошибка произошла. Принято имена таких классов заканчивать суффиксом Exception. Например, класс IOException описывает исключительную ситуацию ввода-вывода.

Теперь о потоках. Чтобы было понятно, представьте себе односторонний туннель, который ведёт к месту назначения. Если в определённой последовательности поместить данные в поток, то в этой же последовательности они окажутся в пункте назначения. Если необходимо прочитать что-то из файла, то нам нужен входящий файловый поток, а если записать, то соответственно исходящий файловый поток. Но мы для работы с файлами используем ещё два потока. Это входящий и исходящий потоки данных. Потоки как и любые классы также наследуются от более старшего класса уточняя их. Я думаю это станет ясно, если мы посмотрим на следующую последовательность: InputStream -> FileInputStream -> DataInputStream. Здесь главным является InputStream, который превращает потоки унаследованные от него именно во входящие потоки. FileInputStream уточняет что это входящий поток из файла, а DataInputStream говорит о том что поступающая информация из потока должна интерпретироваться как данные. Соответственно каждый вид потока имеет свои методы для удобной работы с ним. При создании потока, ему выделяется значительная часть памяти, поэтому после окончания работы с ним его необходимо корректно закрыть, а не оставлять эту работу самой системе, так как неизвестно когда она посчитает что его следует уничтожить и освободить занимаемые им ресурсы.


Нравится


Гость
Сообщения:

Гость, мы рады Вас видеть.
Пожалуйста зарегистрируйтесь или войдите под своим логином.
Поиск
«  Январь 2025  »
ПнВтСрЧтПтСбВс
  12345
6789101112
13141516171819
20212223242526
2728293031
Содержание
Наш опрос
Какими языками программирования Вы владеете?

Результаты Архив опросов


Всего голосовало: 50
Обсудить опрос на форуме
Друзья сайта
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
free counters



Каталог сайтов Нашли.com - тематический каталог сайтов, поиск Каталог сайтов - Первый в WWW