T.M. SoftStudio

feci quod potui, faciant meliora potentes

Купить полную версию курса "Введение в вычисления с Java" (русскоязычная версия, лекции, тесты, лабораторные работы)

Введение в вычисления с Java. Символьные строки, File IO

Неделя 7

Лекция 31

File IO

Программы, которые мы писали до сих пор, в основном полагались на консольный ввод-вывод.

Это часто не очень эффективно, если нужно иметь дело с большим количеством входных данных.

Например, информация о всех студентах в классе, где может быть более 100 студентов.

Это также очень раздражает, если нужно обеспечить одинаковый набор входных данных каждый раз, когда вы хотите запустить программу, особенно на стадии разработки программы.

Бывает и так, часто, когда при завершении работы программы, которая производит некоторые результаты, результаты должны быть где-нибудь сохранены.

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

Итак, что представляет собой файл? Мы используем файлы все время.

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

Изображения, которые мы использовали, хранятся в файлах.

Программный интерфейс File IO, который мы собираемся использовать здесь, имеет дело только с простыми текстовыми файлами.

Это пример текстового файла, содержащего список имен.

Это может быть список имен студентов в классе.

Тип файлов – .text, и имя конкретно этого файла studentnames.text.

Как вы можете видеть из этого примера, данные, хранящиеся в этом файле, организованы построчно и на каждой строке содержится последовательность символов.

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

Когда имеешь дело с файлом, первый шаг, как правило, это открыть файл, если файл уже существует,  или создать файл, если файл еще не создан.

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

Важным шагом является, когда использование файла завершено, закрыть файл.

Способом открыть файл в Java является связывание некоторого объекта с файлом.

Чтобы установить соответствие между объектом и файлом, мы будем использовать классы File/PrintWriter/Scanner.

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

Пакет java.io содержит много классов, которые можно использовать для программ с вводом и выводом данных.

Это пакеты, которые должны быть импортированы в начале вашей программы.

Работа с File IO может сопровождаться ошибками.

Пользователь может ввести неправильное имя файла или может не иметь права доступа к файлу.

Также может быть проблема с устройствами хранения данных, например, диск может быть полностью заполнен.

Поэтому обработка исключений или ошибок необходима при выполнении File IO.

Правильным способом обработки исключений является использование блока try-catch в виде приведенном здесь.

Однако, обработка исключений, выходит за рамки данного курса.

Одним из способов обхода обработки исключений является добавление «throws IOexception» после заголовка метода, когда файловый ввод/вывод выполняется в методе.

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

Давайте сначала обсудим ввод данных из файла с помощью класса Scanner.

Способ, которым Java открывает файл, это связать объект с файлом.

То есть установить соответствие между объектом файла и файлом, указанным с помощью имени файла.

После того, как устанавливается соответствие, объект Scanner может быть создан с помощью объекта файла.

После того, как файл открыт, то следующим шагом является чтение данных из файла.

Мы сначала сосредоточимся на чтении данных из файла, строка за строкой.

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

Scanner прерывает свой ​​ввод последовательностей лексем в соответствии с конкретными правилами, используя шаблон разделителя, по умолчанию, пробел используется в качестве разделителя для лексем.

Scanner обеспечивает методы для преобразования вводимого текста в соответствующие типы Java, в том числе примитивные типы и тип String.

Вот некоторые из полезных методов в классе Scanner.

На левой стороне, методы для чтения содержимое из файла, в том числе nextLine(), который возвращает следующую линию строки.

Метод next() возвращает следующую строку.

Только первая будет возвращена, если строка содержит много слов.

Методы nextInt() и nextDouble() читают следующую строку, а затем преобразовывают ее в целое, если nextInt() используется, и число с плавающей точкой, если nextDouble() используется.

Методы на правой стороне, проверяют наличие контента в файле.

Метод hasNextLinе() возвращает true, если следующая линия существует.

Метод hasNext() возвращает true, если есть еще следующая строка.

Методы hasNextInt() и hasNextDouble() возвращают true, если есть еще целое или число с плавающей запятой в файле.

Пример использования Scanner

Чтобы показать, как использовать Scanner для выполнения файлового ввода, рассмотрим простую программу, которая открывает текстовый файл, читает файл построчно, а затем распечатывает строки ввода по одной в консоли.

Метод называется readStudentNamesFromFile.

Как я упоминал ранее, метод обрабатывает исключение ввода-вывода с помощью throws в сигнатуре метода, объявляя возможное исключение.

Внутри метода, объект файла inputFile объявляется чтобы быть связанным с файлом, с именем, заданным в качестве параметра в конструкторе класса File.

В этом примере, именем файла является studennames.txt.

Это тот же файл, что мы видели ранее.

После того, как соответствие между объектом файла и самим файлом устанавливается, объект Scanner с именем input для входного файла.

Файл открывается.

И содержимое можно прочитать из файла.

В этом методе, цикл for используется для чтения по одной строке за один раз из файла.

Обратите внимание, что в то время как инициализация и обновление индекса цикла i сделаны, используя обычный путь, условие цикла проверяется без ссылки на индекс цикла.

Вместо этого, цикл проверяет, есть ли еще любая оставшаяся новая линия в исходном файле для чтения с помощью метода hasNextLine.

Поэтому, цикл будет продолжаться, пока не достигнет конца файла.

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

Внутри цикла, метод nextLine используется для чтения следующей строки, и результат присваивается переменной String inputStudentName.

Эта программа будет просто выводить каждую строку, извлеченную из файла, добавляя ее к строке Student # i.

Когда программа завершит цикл, входной файл должен быть закрыт перед выходом из метода.

Здесь показаны скриншоты двух окон, в том числе вывод программы, с соответствующим входом.

Пример использования PrintWriter

Подобно тому, что мы сделали с входными файлами, для того, чтобы сделать вывод файла, мы должны сначала связать объект File с файлом, указанным в имени файла.

После того, как устанавливается соответствие, объект PrintWriter может быть создан с помощью объекта File.

После того, как файл открыт, мы можем начать вывод данных в файл.

Вы можете использовать print или рrintln метод для печати значений различных типов, в том числе примитивных типов и строк в файле.

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

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

В противном случае, вы можете потерять все данные в файле.

Здесь мы используем метод, который мы только что обсудили, который использует Scanner для считывания данных из входного файла и выводит результаты на консоль.

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

Следуя четырех шаговому процессу, который мы только что описали, объект File и объект PrintWriter будут созданы для файла с именем output.txt, который используется в качестве параметра для конструктора файла, когда объект outputFile создается.

После создания outputFile, объект PrintWriter может использовать метод рrintln для вывода результатов.

Итак, вот, метод writer.printIn() используется для замены IO.outputln, так что результаты будут напечатаны в файл, а не в консоль.

Когда вся работа сделана, перед выходом из программы, как выходные, а также входные файлы должны быть закрыты с помощью метода close.

Чтобы убедиться, что программа действительно закончила работу в соответствии с требованиями, вот скриншот содержания двух файлов с output.txt и studentnames.txt.

Оба открыть с помощью блокнота.

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

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