Главная » Java, Web » Имена. Каталоги. Класс File

0

Полное имя файла состоит из имени файла как такового и имени каталога, в котором располагается этот файл. Простые имена файлов, например, такие как data.dat или result.dat, используются только для обращения к файлам, расположенным в текущем (или рабочем) каталоге. К другим файлам следует обращаться с указанием полного имени, включая имя каталога.

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

?   data.dat — на любом компьютере, это имя файла в текущем каталоге;

?   /home/eck/ j ava/examples/data. dat — абсолютный путь на системе UNIX;

?   C:\eck\java\examples\data.dat — абсолютный путь для DOS и Windows;

?   Hard Drive: j ava: examples: data, dat — ДЛЯ системы Macintosh OS 9 (Hard Drive — имя устройства);

?   examples/data.dat — относительный путь на UNIX;

?   examples\data.dat — относительный путь для DOS и Windows;

?   examples: data. dat — относительный путь для Macintosh.

Чтобы хотя бы в этом избежать проблем, вызванных различиями в платформах, в языке Java используется класс java.io.Fiie. Объект этого класса представляет файл, точнее не сам файл, а имя файла. Сам файл может либо существовать, либо не существовать. Каталоги воспринимаются точно так же, как и файлы. Объект типа File с равным успехом может представлять как файл, так и каталог.

Объект File создается при помощи конструктора File (string), которому в качестве параметра передается путь к файлу с именем файла. Имя может быть указано как в абсолютной, так и в относительной форме. Например, new File ("data.dat") создает объект типа File, который ссылается на файл data.dat, расположенный в текущем каталоге. Существует другой тип конструктора для создания объекта типа File, new File (File, String), В ЭТОМ конструкторе указывается два параметра. Первый — объект типа File, который ссылается на каталог, в котором расположен файл, имя файла (простое) указывается во втором аргументе.

Объект типа File обладает набором полезных методов. Пусть file — это объект типа File, перечислим некоторые полезные методы при работе с объектом типа File.

?   file.exists о — логическое значение. Возвращает true, если файл с установленным именем файла существует. Этот метод полезно использовать в том случае, если мы желаем избежать возможной потери данных, записанных в уже существующем файле перед использованием FileWriter.

?   fiie. isDirectory () — логическое значение. Возвращает true, если объект указывает на каталог. Если объект указывает на обычный файл или если каталог с заданным именем не существует, возвращает false.

?   file.delete о — удаляет файл, если файл существует.

?   file, list о — если объект указывает на каталог, то функция возвращает массив типа string п , в котором содержатся имена файлов в данном каталоге. В противном случае возвращает null.

Ниже приведен пример программы (листинг 2.3), которая возвращает имена всех файлов, расположенных в указанном пользователем каталоге (рис. 2.1):

Листинг 2.3. Программа, выводящая на экран список файлов в каталоге

import java.io.File; public class DirectoryList {

public static void main(String[] args) {

String directoryName; // имя каталога, вводимое пользователем File directory;    // объект типа File, указывающий на каталог

String[] files;           // массив имен файлов в каталоге

TextlO.put ("wedite imya kataloga: "); directoryName = TextIO.getln().trim() ; directory = new File(directoryName); if (directory.isDirectory() == false) { if (directory.exists() == false)

TextlO.putln("Takogo kataloga net!"); else

TextlO.putln("Eto ne katalog.");

}

else {

files = directory.list ();

TextlO.putln("Spisok failov v kataloge V" + directory + for (int i = 0; i < files.length; i++) Text10.putIn(" " + files [i]);

}

Все классы, которые читают и пишут данные из файла или в файл, получают в качестве параметра объект типа File. Например, если file — это переменная типа File, то мы можем создать поток FiieReader, указав new FiieReader (file). Если используется TextReader для чтения из файла, то можно применить следующую конструкцию:

TextReader data; try {

data = new TextReader(new FileReader(file));

catch (FileNotFoundException e) { … // обработка ошибок

Рис. 2.1. Программа выводит список файлов в каталоге

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

Следующий пример создает список всех слов, встречающихся в заданном файле. Под словом понимается последовательность букв. Пользователь должен ввести имя файла. Список слов выводится в другой файл, который также задается пользователем. Список слов будет выведен в алфавитном порядке, причем слова не будут повторяться. Все буквы в словах будут приведены к нижнему регистру. Например, слова "The" и "the" буцут восприниматься как одно и то же слово.

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

нам будет необходимо. Программа содержится в файле WordList.java (листинг 2.4).

В программе использован класс Textio, полностью файл TextlO.java приводится в приложении 4.

Листинг 2.4. Файл WordList.java

import java.io.*; public class WordList {

static String[] words; // массив, хранящий слова static int wordCount; // текущее число слов, хранимых в массиве public static void main(String[] args) { TextReader in; // поток для чтения PrintWriter out; // поток для записи String inputFileName; // имя исходного файла String outputFileName; // имя файла для записи words = new String[10]; wordCount = 0; I*

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

Ч

Text10.put("Input file name? "); inputFileName = TextIO.getln().trim(); try {

in = new TextReader(new FiieReader(inputFileName));

}

catch (FileNotFoundException e) {

TextlO.putln("Fail ne suschestvuet: V" + inputFileName + return;

}

/*

Получаем от пользователя имя файла для записи слов. При возникновении IOException печатаем сообщение и прекращаем выполнение программы. *1

TextlO.put("Output file name? "); outputFileName = TextlO.getln().trim (); try {

out = new PrintWriter(new FileWriter(outputFileName));

}

catch (IOException е) {

TextlO.putln("Can’t open file V" + outputFileName +

"\" for output."); TextlO.putln(e.toString()); return;

}

/*

Чтение слов из потока ввода и вставка в массив слов. Чтение может привести к возникновению ошибки TextReader.Error. Тогда печатаем сообщение и прекращаем выполнение программы. */

try {

while (true) {

// Пропускаем небуквенные символы. Читаем слово и вставляем // его в массив.

while (! in.eof() && ! Character.isLetter(in.peek()))

in.getAnyChar(); if (in.eof()) break;

insertWord(in.getAlpha());

}

}

catch (TextReader.Error e) {

TextlO.putln("Oshibka pri chetenii faila.");

TextlO.putln(e.toString());

return;

}

// пишем все слова в поток вывода for (int i = 0; i < wordCount; i++) out.println(words[i]);

/*

Завершаем. Проверяем наличие ошибок при записи.

Выводим на экран либо предупреждение, либо сообщение о количестве записанных слов. */

if (out.checkError() == true) {

Text10.putIn("Some error occured while writing output."); TextlO.putln("Output might be incomplete or invalid.");

}

else {

TextlO.putln(wordCount + " words from + inputFileName + output to + outputFileName +

}

}

static void insertWord(String w) {

// Вставляем слово w в массив слов, если его там еще нет. Все

// слова записаны строчными буквами. Слова в массиве хранятся

//в алфавитном порядке. Если массива по длине становится

// недостаточно, то его размер удваивается.

int pos = 0; // место в массиве для хранения слова w

w = w.toLowerCase();

// определение места в массиве для хранения слова w while (pos < wordCount && words[pos].compareTo(w) < 0) pos++;

if (pos < wordCount && words[pos].equals(w)) return;

/*

Если массив полон, то создаем новый массив, который в 2 раза больше старого. Копируем все слова в новый массив. */

if (wordCount = words.length) {

String[] newWords = new String[words.length*2]; System.arraycopy(words,0,newWords,0,wordCount); words = newWords;

}

/*

Располагаем слово w в нужное место в массиве. Все слова после него сдвигаем на одну позицию далее. */

for (int i = wordCount; i > pos; i—) words[i] = words[i—1]; words[pos] = w; wordCount++;

}

}

Предположим, следующий текст сохранен в файле input.txt:

Виктория, поздравляю тебя с днем рождения! Разреши пожелать тебе всего самого хорошего.

Запускаем программу, вводим запрашиваемые имена (рис. 2.2). В результирующем файле output.txt получаем список слов:

виктория всего

днем

пожелать

поздравляю

разреши

рождения

с

самого

тебе

тебя

хорошего

Рис. 2.2. Пример организации работы с файлами

В качестве следующего примера рассмотрим программу, которая производит копирование файла. Это полезно еще и потому, что многие операции с файлами похожи на копирование файлов, с той разницей, что файл не просто копируется, но производятся некоторые действия с данными, хранящимися в исходном файле. Поскольку программа должна уметь копировать любой файл, мы не можем заведомо предположить, что файл содержит данные, предназначенные для чтения человеком. Поэтому мы будем использовать потоки InputStream И OutputStream, а не ПОТОКИ Reader и Writer. Программа попросту копирует все данные, получаемые из потока inputstream, записывая их в поток OutputStream байт за байтом. Если переменная source ссылается на поток inputstream, то функция source.read () читает из потока байт за байтом. Функция возвращает -1, когда все байты прочитаны. Аналогично, если сору — это поток типа

Outputstream, то метод copy.write (b) пишет один байт в соответствующий файл вывода. Поэтому основу программы составляет простой цикл while, while(true) {

int data = source.read() ; if (data < 0)

break; copy.write(data);

В системах DOS и UNIX для копирования файлов используется команда, записываемая в командной строке как "сору originai.dat backup.dat", при помощи этой команды можно скопировать существующий файл original.dat в новый файл с именем backup.dat. Аргументы, используемые в командной строке, можно применять и в программе, написанной на языке Java. Аргументы командной строки хранятся в строковом массиве args (листинг 2.5), который является аргументом функции main о. Если, например, программа с именем copyFiie использует аргументы, то команда "java CopyFiie work.dat oldwork.dat" приведет к тому, что элемент args[0] будет содержать строку "work.dat", args[l] будет содержать "oldwork.dat". Значение args. length сообщает длину массива аргументов.

Программа copyFiie получает имена файлов из командной строки. Программа выводит сообщение об ошибке в том случае, если имена файлов не заданы. Чтобы сделать программу несколько более интересной, она построена таким образом, что может быть вызвана либо с двумя, либо с тремя аргументами. В первом случае программа в качестве аргументов получает имя файла-источника и имя файла, куда будет скопирован исходный файл. Если последний файл уже существует, то программа выдаст сообщение об ошибке и не будет копировать файл, чтобы не потерять данные, хранящиеся во втором файле. В случае с тремя аргументами в качестве первого аргумента следует задать модификатор -f. Его появление изменяет поведение программы, он сообщает программе о том, что если файл, куда будет производиться копирование, уже существует, то в него разрешается запись.

Листинг 2.5. Файл CopyFile.java                                                                                                       I

import java.io.*;

public class CopyFiie {

public static void main(String[] args) {

String sourceName; // имя исходного файла

// указывается в командной строке String copyName;    // имя файла для копирования

// указывается в командной строке InputStream source; // поток чтения файла Outputstream сору; // поток записи

boolean force;            11 если задана опция -f, то значением

// будет true

int byteCount; // количество байт, скопированных из файла /*

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

if (args.length == 3 && args[0].equalsIgnoreCase("-f")) { sourceName = args[l]; copyName = args[2]; force = true;

}

else

if (args.length ==2) { sourceName = args[0]; copyName = args[l]; force = false;

}

else {

System.out.printIn(

"Pravilno pisat tak: java CopyFile <source-file> <copy-name>"); System.out.printIn(

" ili java CopyFile -f <source-file> <copy-name>"); return;

}

/*

создаем поток ввода, если появляется ошибка, останавливаем выполнение программы */

try {

source = new FilelnputStream(sourceName);

}

catch (FileNotFoundException e) {

System.out.println("Can’t find file + sourceName+ ."); return;

}

/*

если файл вывода уже существует и опция -f не задана, то выводим сообщение об ошибке и прекращаем выполнение программы */

File file = new File(copyName); if (file.exists() && force == false) {

System.out.printIn("Fail uzhe suschestvuet. Ispolzujte -f dlya perezapisi fajla.");

return;

}

/*

Создаем поток вывода. При возникновении ошибки пишем сообщение и прекращаем выполнение программы. */ try {

сору = new FileOutputStream(copyName);

}

catch (IOException e) {

System.out.println("Can’t open output file V" + copyName + "\".");

return;

}

/*

Копируем по одному байту раз за разом до тех пор, пока метод read() не возвратит -1 (достигнут конец потока ввода). При возникновении ошибки выводим сообщение об ошибке. При удачном копировании выводим сообщение о том, что копирование прошло успешно. */ byteCount = 0; try {

while (true) {

int data = source.read(); if (data < 0)

break; copy.write(data); byteCount++;

}

source.close (); copy.close();

System.out.println("Uspeshno skopirovano " + byteCount + " bait.");

}

catch (Exception e) {

System.out.println("Vo vremya kopirovaniya proizoshla oshibka.

Vsego skopirovano " + byteCount + " bait."); System.out.println(e.toString());

В качестве заключительного примера работы с файлами приведем программу, которая использует графический интерфейс пользователя для чтения и записи файла (листинг 2.6). Программа, как это обычно бывает, содержит пункт меню Open. При переходе по нему пользователю будет предложено выбрать открываемый файл. Сохранение файла происходит при обращении к пункту меню Save. Окно программы содержит в себе в качестве основного компонента текстовую область jTextArea, которая может содержать некоторый текст и использоваться для редактирования текста. В верхней части располагается панель меню, в которой находится меню File, содержащее команды Open и Save. При нажатии кнопки Save в меню File появляется диалоговое окно, где пользователю предлагается выбрать имя файла, куда будет записан текст, расположенный в окне редактирования текста. Имя файла можно ввести вручную (рис. 2.3).

Рис. 2.3. Диалоговое окно выбора файла

Для открытия файла также предлагается диалоговое окно, вызываемое командой Open меню File (рис. 2.4).

Рис. 2.4. Диалоговое окно открытия файла

Листинг 2.6. Файл TrlvlalEdlt.java

import java.io.*; impo rt j ava.awt.* ; impo rt j ava.awt.event.* ; import javax.swing.* ;

public class TrivialEdit extends JFrame { public static void main(String[] args) { // основная программа, открывающая окно new TrivialEdit();

}

private JTextArea text; // окно редактирования текста public TrivialEdit() {

// Вставляет панель меню. Первая строка вызывает конструктор

// суперкласса для создания заголовка окна. Команда pack()

// задает размер окна.

super("A Trivial Editor");

setJMenuBar(makeMenus());

text = new JTextArea(25,50);

text.setBackground(Color.white);

text.setMargin(new Insets(3,5,0,0) ) ;

JScго11Pane scroller = new JScrollPane(text); setContentPane(scroller); setDefaultCloseOperation(EXIT_ON_CLOSE); pack () ;

setLocation(50,50); show();

}

private JMenuBar makeMenus () {

// Создает панель меню с одним разделом меню File. Этот раздел содержит // четыре команды. Каждой команде соответствует эквивалент, // вызываемый при помощи клавиатуры ("горячие клавиши" – hot keys). ActionListener listener = new ActionListener() {

// Объект, который служит прослушивателем для элементов меню, public void actionPerformed(ActionEvent evt) {

// Метод вызывается, когда пользователь производит

// выбор в меню File. Функция проверяет, какой выбор

// сделан, и вызывает другую функцию для выполнения

// выбранной команды.

String cmd = evt.getActionCommand();

if (cmd.equals("New"))

doNew(); else

if (cmd.equals("Open…"))

doOpen(); else

if (cmd.equals("Save…"))

doSave(); else

if (cmd.equals("Quit")) doQuit ();

}

} ;

JMenu fileMenu = new JMenu("File");

JMenuItem newCmd = new JMenuItem("New");

newCmd.setAccelerator(Keystroke.getKeyStroke("ctrl N"));

newCmd.addActionListener(listener);

fileMenu.add(newCmd);

JMenuItem openCmd = new JMenuItem("Open…"); openCmd.setAccelerator(Keystroke.getKeyStroke("ctrl 0")); openCmd.addActionListener(listener); fileMenu.add(openCmd);

JMenuItem saveCmd = new JMenuItem("Save…"); saveCmd.setAccelerator(Keystroke.getKeyStroke("ctrl S")); saveCmd.addActionListener(listener); fileMenu.add(saveCmd);

JMenuItem quitCmd = new JMenuItem("Quit");

quitCmd.setAccelerator(Keystroke.getKeyStroke("Ctrl Q"));

quitCmd.addActionListener(listener);

fileMenu.add(quitCmd);

JMenuBar bar = new JMenuBar();

bar.add(fileMenu);

return bar;

}

private void doNew() {

// Создание нового файла. // Очистка текстовой области JTextArea. text.setText ("");

}

private void doSave() {

// Выполнение команды Save. Выбор файла по указанию // пользователя. Запись текста из текстовой // области JTextArea в указанный файл.

File file; // файл, в который будет производиться запись JFileChooser fd; // диалоговое окно выбора файла fd = new JFileChooser(new File(".")) ; fd.setDialogTitle("Save Text As…"); int action = fd.showSaveDialog(this); if (action != JFileChooser.APPROVF_OPTION) { // отмена или появилась ошибка return;

}

file = fd.getSelectedFile() ; if (file.exists ()) {

// если файл уже существует, то перед перезаписью выводим вопрос action = JOptionPane.showConfirmDialog(this,

"Perepisat suschestvuyuschij fail?") ; if (action != JOptionPane.YFS_OPTION) return;

}

try {

// создаем PrintWriter для записи в указанный файл и пишем // текст из окна в созданный поток

PrintWriter out = new PrintWriter(new FileWriter(file)); String contents = text.getText(); out.print(contents); if (out.checkFrror())

throw new IOException("Oshibka zapisi v fail."); out.close ();

}

catch (IOException e) {

// Voznikla oshibka pri zapisi f fail. // Vyvodim soobscheinie ob oshibke.

JOptionPane.showMessageDialog(this, "Proizoshla oshibka:\n" + e.getMessage());

}

}

private void doOpen() {

// Открытие файла по указанию пользователя. // Выбор производится в диалоговом окне. Содержимое файла // заменяет текст, расположенный в текстовом окне JTextArea. File file; // файл, который пользователь выбрал для открывания JFileChooser fd; // диалоговое окно выбора файла fd = new JFileChooser(new File (".")); fd.setDialogTitle("Open F7ile…"); int action = fd.showOpenDialog(this) ; if (action != JFileChooser.APPROVE_OPTION) { // отмена или ошибка return;

}

file = fd.getSelectedFile(); try {

// Чтение строк файла до достижения конца файла. Строки

// вставляются в текстовую область. После каждой строки

// вставляется символ перевода строки.

TextReader in = new TextReader(new FileReader(file));

String line;

text.setText("");

int lineCt = 0;

while (lineCt < 100 && in.peek() != ‘\0′) {

line = in.getln();

text.append(line + ‘\n’);

lineCt++;

}

if (in.eof() == false)

text.append("\n\n******* Text sokraschen do 100 strok! *******\n«);

in.close ();

}

catch (Exception e) {

// ошибка при чтении файла

JOptionPane.showMessageDialog(this,

"Sorry, some error occurred:\n" + e.getMessage());

}}

private void doQuit() {

// выполняется команда выхода Quit System.exit(0);

Источник: Будилов В. А. Интернет-программирование на Java. — СПб.: БХВ-Петербург, 2003. — 704 е.: ил.

По теме:

  • Комментарии