Главная Случайная страница


Категории:

ДомЗдоровьеЗоологияИнформатикаИскусствоИскусствоКомпьютерыКулинарияМаркетингМатематикаМедицинаМенеджментОбразованиеПедагогикаПитомцыПрограммированиеПроизводствоПромышленностьПсихологияРазноеРелигияСоциологияСпортСтатистикаТранспортФизикаФилософияФинансыХимияХоббиЭкологияЭкономикаЭлектроника






DataInputStream и DataOutputStream

До сих пор речь шла только о считывании и записи в поток данных в виде byte. Для работы с другими примитивными типами данных Java определены интерфейсы DataInput и DataOutput и их реализации – классы-фильтры DataInputStream и DataOutputStream.

Интерфейсы DataInput и DataOutput определяют, а классы DataInputStream и DataOutputStream соответственно реализуют методы считывания и записи значений всех примитивных типов. При этом происходит конвертация этих данных в набор byte и обратно. Чтение необходимо организовать так, чтобы данные запрашивались в виде тех же типов, в той же последовательности, как и производилась запись. Если записать, например, int и long, а потом считывать их как short, чтение будет выполнено корректно, без исключительных ситуаций, но числа будут получены совсем другие.

 

Пример 2.4

try { ByteArrayOutputStream out = new ByteArrayOutputStream(); DataOutputStream outData = new DataOutputStream(out); outData.writeByte(128); // этот метод принимает аргумент int, но записывает // лишь младший байт outData.writeInt(128); outData.writeLong(128); outData.writeDouble(128); outData.close(); byte[] bytes = out.toByteArray(); InputStream in = new ByteArrayInputStream(bytes); DataInputStream inData = new DataInputStream(in);

System.out.println("Correct sequence reading:");

System.out.println("readByte: " + inData.readByte()); System.out.println("readInt: " + inData.readInt()); System.out.println("readLong: " + inData.readLong()); System.out.println("readDouble: " + inData.readDouble()); inData.close(); System.out.println("Inverted sequence reading:"); in = new ByteArrayInputStream(bytes); inData = new DataInputStream(in); System.out.println("readInt: " + inData.readInt()); System.out.println("readDouble: " + inData.readDouble()); System.out.println("readLong: " + inData.readLong()); inData.close(); } catch (Exception e) { System.out.println("Impossible IOException occurs: " + e.toString()); e.printStackTrace();}

Результат выполнения программы:

Correct sequence reading:

readByte: -128

readInt: 128

readLong: 128

readDouble: 128.0

Inverted sequence reading:

readInt: -2147483648

readDouble: -0.0

readLong: -9205252085229027328

 

Класс File

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

Объект класса File является абстрактным представлением файла и пути к нему. Он устанавливает только соответствие с ним, при этом для создания объекта неважно, существует ли такой файл на диске. После создания можно выполнить проверку, вызвав метод exists, который возвращает значение true, если файл существует. Создание или удаление объекта класса File никоим образом не отображается на реальных файлах. Для работы с содержимым файла можно получить экземпляры FileI/OStream.

Объект File может указывать на каталог (узнать это можно путем вызова метода isDirectory()). Метод list возвращает список имен (массив String) содержащихся в нем файлов (если объект File не указывает на каталог, будет возвращен null).

Следующий пример демонстрирует использование объектов класса File.

 

Пример 2.5

import java.io.*; public class FileDemo { public static void findFiles(File file, FileFilter filter, PrintStream output) throws IOException{ if (file.isDirectory()) { File[] list = file.listFiles(); for (int i=list.length; --i>=0;) { findFiles(list[i], filter, output); } } else { if (filter.accept(file)) output.println("\t" + file.getCanonicalPath()); } } public static void main(String[] args) { class NameFilter implements FileFilter { private String mask; NameFilter(String mask) { this.mask = mask; } public boolean accept(File file){ return (file.getName().indexOf(mask)!=-1)?true:false; } } File pathFile = new File("."); String filterString = ".java"; try { FileFilter filter = new NameFilter(filterString); findFiles(pathFile, filter, System.out); } catch(Exception e) { e.printStackTrace(); } System.out.println("work finished"); } }

При выполнении этой программы на экран будут выведены названия (в каноническом виде) всех файлов с расширением .java, содержащихся в текущем каталоге и всех его подкаталогах.

Для определения того, что файл имеет расширение .java, использовался интерфейс FileFilter с реализацией в виде внутреннего класса NameFilter. Интерфейс FileFilter определяет только один метод accept, возвращающий значение, определяющее, попадает ли переданный файл в условия фильтрации. Помимо этого интерфейса, существует еще одна разновидность интерфейса фильтра – FilenameFilter, где метод accept определен несколько иначе: он принимает не объект файла к проверке, а объект File, указывающий на каталог, где находится файл для проверки, и строку его названия. Для проверки совпадения с учетом регулярных выражений нужно соответствующим образом реализовать метод accept. В конкретном приведенном примере можно было обойтись и без использования интерфейсов FileFilter или FilenameFilter. На практике их можно использовать для вызова методов list объектов File – в этих случаях будут возвращены файлы с учетом фильтра.

Также класс File предоставляет возможность получения некоторой информации о файле:

· методы canRead и canWrite – возвращается boolean-значение, можно ли будет приложению производить чтение и изменение содержимого из файла, соответственно;

· getName – возвращает строку – имя файла (или каталога);

· getParent, getParentName – возвращают каталог, где файл находится в виде строки названия и объекта File соответственно;

· getPath – возвращает путь к файлу (при этом в строку преобразуется абстрактный путь, на который указывает объект File);

· isAbsolutely – возвращает boolean значение, является ли абсолютным путь, которым указан файл. Определение, является ли путь абсолютным, зависит от системы, где запущена Java-машина. Так, для Windows абсолютный путь начинается с указания диска, либо символом '\'. Для Unix абсолютный путь начинается символом '/' ;

· isDirectory, isFile – возвращает boolean значение, указывает ли объект на каталог либо файл соответственно;

· isHidden – возвращает boolean значение, указывает ли объект на скрытый файл;

· lastModified – дата последнего изменения;

· length – длина файла в байтах.

Также можно изменить некоторые свойства файла – методы setReadOnly, setLastModified, назначение которых очевидно из названия. Если нужно создать файл на диске, это позволяют сделать методы createNewFile, mkDir, mkDirs. Соответственно createNewFile создает пустой файл (если таковой еще не существует), mkDir создает каталог, если для него все родительские уже существуют, а mkDirs создает каталог вместе со всеми необходимыми родительскими.

Файл можно и удалить – для этого предназначены методы delete и deleteOnExit. При вызове метода delete файл будет удален сразу же, а при вызове deleteOnExit по окончании работы Java-машины (только при корректном завершении работы) отменить запрос уже невозможно.

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

 

Класс RandomAccessFile

Этот класс реализует сразу два интерфейса – DataInput и DataOutput – следовательно, может производить запись и чтение всех примитивных типов Java. Эти операции, как следует из названия, производятся с файлом. При этом их можно производить поочередно, произвольным образом перемещаясь по файлу с помощью вызова метода seek(long) (переводит на указанную позицию в файле). Узнать текущее положение указателя в файле можно вызовом метода getFilePointer.

При создании объекта этого класса конструктору в качестве параметров нужно передать два параметра: файл и режим работы. Файл, с которым будет проводиться работа, указывается либо с помощью String – название файла, либо объектом File, ему соответствующим. Режим работы (mode) – представляет собой строку либо «r» (только чтение), либо «rw» (чтение и запись). Попытка открыть несуществующий файл только на чтение приведет к исключению FileNotFoundException. При открытии на чтение и запись он будет незамедлительно создан (или же будет брошено исключение FileNotFoundException, если это невозможно осуществить).

После создания объекта RandomAccessFile можно воспользоваться методами интерфейсов DataInput и DataOutput для проведения с файлом операций считывания и записи. По окончании работы с файлом его следует закрыть, вызвав метод close.

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

 

Пример 2.6

import java.io.*;

public class Lab1

{

private String data;

private String filename;

private String choice;

private RandomAccessFile fio;

private BufferedReader in=

new BufferedReader(new InputStreamReader(System.in));

public void runConsol(){

while(true){

try{

System.out.println("\nEnter your choice:");

System.out.println("1.Read text from file");

System.out.println("2.Type text");

System.out.println("3.Exit");

//чтение выбора пользователя

choice=in.readLine();

if (choice.compareTo("1")==0){

System.out.println("Type your filename");

filename=in.readLine();

fio = new RandomAccessFile(new File(filename), "r");

data=fio.readLine();

fio.close();

System.out.println("\nFile Input:\n"+data);

int spaces=0, glas=0, lett=0;

char ch;

for(int i=0;i<data.length();i++)

{

ch=Character.toLowerCase(data.charAt(i));

if(Character.isWhitespace(ch))

spaces++; if((ch=='a')||(ch=='e')||(ch=='i')||(ch=='o')||(ch=='u')||(ch=='y'))

glas++;

lett++;

}

System.out.println("\nspaces - "+spaces+"\nvowels - "+glas+"\nletters - "+(lett-spaces));

}

else if (choice.compareTo("2")==0){

System.out.println("Type your text");

data=in.readLine();

System.out.println("Type your filename");

filename=in.readLine();

fio = new RandomAccessFile(new File(filename), "rw");

fio.writeBytes(data);

fio.close();

System.out.println("Your text was saved");

}

else if (choice.compareTo("3")==0){

return;

}

}

catch(FileNotFoundException e){

System.out.println("File not found");

}

catch(IOException e){

System.out.println("Error1");

}

catch(Exception e){

System.out.println("Error2");

}

}

}

}

 

Результат выполнения программы:

Enter your choice:

1.Read text from file

2.Type test

3.Exit

Выбрав 2-й вариант, введем строку и имя файла, где необходимо сохранить строку. После этого будет предложено снова осуществить выбор.

Теперь выберем 1-й вариант. Введем имя нашего файла. В результате выведется исходная строка и итоги ее анализа: количество пробелов, гласных и общее количество букв. И снова будет предложен выбор.

Теперь выберем 3-й вариант. После этого программа завершит свою работу.

 

Задания для самостоятельного выполнения

 

Используя варианты заданий к лабораторной работе №1, разработать программу, которая позволяла бы работать с тремя файлами. Исходная информация должна хранить в файле file1.txt (программа ее считывает и осуществляет с ней преобразования), затем преобразованная информация записывается в файл file2.txt, а в файл file3.txt программа должна записать исходную и преобразованную информацию.

 


ЛАБОРАТОРНАЯ РАБОТА №3

Последнее изменение этой страницы: 2016-08-11

lectmania.ru. Все права принадлежат авторам данных материалов. В случае нарушения авторского права напишите нам сюда...