- Файлы и директории, класс File
- Примеры создания объектов File
- Свойства и методы класса File
- Интерфейс FileFilter
- Пример использования фильтра FileFilter
- Чтение содержимого файла FileInputStream
- Запись в файл FileOutputStream
- Creating and Reading Directories
- Listing a File System’s Root Directories
- Creating a Directory
- Creating a Temporary Directory
- Listing a Directory’s Contents
- Filtering a Directory Listing By Using Globbing
- Writing Your Own Directory Filter
Файлы и директории, класс File
Класс File пакета java.io используется для управления информацией о файлах и каталогах. На уровне операционной системы файлы и каталоги имеют существенные отличия, но в Java они описываются одним классом File. Каталог в Java трактуется как обычный файл, но с дополнительным свойством — списком имен файлов, который можно просмотреть с помощью метода list.
В зависимости от назначения объект File — файл или каталог, можно использовать один из конструкторов для создания объекта:
File (String путь_к_каталогу); File (String путь_к_каталогу, String имя_файла); File (File каталог, String имя_файла);
Примеры создания объектов File
// Создание File для каталога File dir = new File("C://dir_test"); // Создание File для файлов, которые находятся в каталоге File file1 = new File("C://dir_test", "Hello1.txt"); File file2 = new File(dir, "Hello2.txt");
Свойства и методы класса File
Для определения стандартных свойств файла в классе File имеются различные методы. Однако класс File несимметричен, т.е. методы определения свойств объекта существуют, но соответствующие функции для изменения этих свойств отсутствуют.
Функции | Описание |
---|---|
String getName() | Наименование файла или каталога. |
String getParent() | Наименование родительского каталога. |
long length() | Функция определения размера файла в байтах. |
String getAbsolutePath() | Функция определения абсолютного пути файла или каталога. |
boolean delete() | Удаления файла или каталога. |
boolean exists() | Проверка существования файла или каталога. |
boolean isDirectory() | Проверка, является ли данный объект каталогом. |
boolean isFile() | Проверка, является ли данный объект файлом. |
long lastModified() | Функция определения даты последней модификации файла. |
boolean canRead() | Проверка, можно ли читать данные из файла. |
boolean canWrite() | Проверка, можно ли записывать данные в файл. |
boolean isHidden() | Проверка, являются ли каталог или файл скрытыми. |
String[] list() | Чтение массива наименований файлов и подкаталогов. |
File[] listFiles() | Чтение массива файлов и подкаталогов. |
boolean mkdir() | Создание нового каталога. |
boolean renameTo(File dest) | Переименовывание файла или каталога. |
В следующем примере открываем файл «d:/test/MyFile.txt» (Windows) и извлекаем его характеристики:
import java.io.File; public class FileTest < public static void main(String args[]) < File fl = new File("d:\\test\\MyFile.txt"); System.out.println ("Имя файла: " + fl .getName()); System.out.println ("Путь: " + fl.getPath()); System.out.println ("Полный путь: " + fl.getAbsolutePath()); System.out.println ("Родительский каталог: " + fl.getParent()); System.out.println (fl.exists() ? "Файл существует" : "Файл не существует"); System.out.println (fl.canWrite() ? "Свойство - можно записывать" : "Свойство - нельзя записывать"); System.out.println (fl.canRead() ? "Свойство - можно читать" : "Свойство - нельзя читать"); System.out.println ("Это директория ? " + (fl.isDirectory() ? "да": " нет")); System.out.println ("Это обычный файл ? " + (fl.isFile() ? "да" : "нет")); System.out.println ("Последняя модификация файла : " + fl. lastModified()); System.out.println ("Размер файла : " + fl.length() + " bytes"); >>
В консоли будет отпечатана следующая информация:
Имя файла: MyFile.txt Путь: d:\test\MyFile.txt Полный путь: d:\test\MyFile.txt Родительский каталог: d:\test Файл существует Свойство - можно записывать Свойство - можно читать Это директория ? нет Это обычный файл ? да Последняя модификация файла : 1441710053162 Размер файла : 12 bytes
Интерфейс FileFilter
Класс File включает метод, позволяющий прочитать список только определенных файлов.
public File[] listFiles(FileFilter filter)
В отличие от одноименного метода, но без параметра, данный метод отбирает только те файлы каталога, которые удовлетворяют определенному условию. Параметр filter предназначен для задания этого условия. При этом тип параметра FileFilter — это не класс, а интерфейс, который имеет всего один метод, возвращающий true, если файл удовлетворяет определенным условиям, и false в противном случае.
public boolean accept(File pathname)
Метод listFiles будет вызывать метод accept для каждого файла в каталоге, и те, для которых accept вернет true, будут включены в результирующий список. Остальные будут проигнорированы.
Для использования FileFilter необходимо создать объект и определить в нем соответствующий метод accept.
class Filter implements FileFilter < String[] ext; Filter(String ext) < this.ext = ext.split(","); >private String getExtension(File pathname) < String filename = pathname.getPath(); int i = filename.lastIndexOf('.'); if ((i >0) && (i < filename.length()-1)) < return filename.substring(i+1).toLowerCase(); >return ""; > public boolean accept(File pathname) < if (!pathname.isFile()) return false; String extension = getExtension(pathname); for (String e : ext) < if (e.equalsIgnoreCase(extension)) return true; >return false; > >
Пример использования фильтра FileFilter
import java.io.File; import java.io.FileFilter; public class FileTest < public static void main(String args[]) < // Определение директории File dir = new File("."); // Чтение полного списка файлов каталога File[] lst1 = dir.listFiles(); // Чтение списка файлов каталога // с расширениями "png" и "jpg" File[] lst2 = dir.listFiles(new Filter("png,jpg")); System.out.println ("lst1.length = " + lst1.length + ", lst2.length = " + lst2.length); >>
Чтение содержимого файла FileInputStream
Для чтения содержимого файла можно использовать класс FileInputStream, который является наследником класса InputStream и реализует все его методы. Конструктор класса FileInputStream :
FileInputStream(String fileName) throws FileNotFoundException
Если файл не может быть открыт то генерируется исключение FileNotFoundException.
Пример считывания данных из файла и вывод содержимого в консоль:
import java.io.FileInputStream; public class FilesApp < public static void main(String[] args) < try < FileInputStream fis; fis=new FileInputStream("C:\\test_dir\\test.txt"); System.out.println("Размер файла: " + fis.available() + " байт(а)"); int i = -1; while(( i = fis.read()) != -1)< System.out.print((char)i); >fis.close(); > catch(IOException e) < System.out.println(e.getMessage()); >> >
Данные файла можно считать в массив байтов :
byte[] buffer = new byte[fis.available()]; // чтение файла в буфер fis.read (buffer, 0, fis.available()); System.out.println («Содержимое файла:»); for(int i = 0; i
Класс FileInputStream предназначен прежде всего для работы с двоичными файлами. Его можно использовать для работы с текстовыми файлами, но все же для этой задачи больше подходят другие классы.
Пример использования FileInputStream для чтения файла свойств в кодировке UTF-8:
Файл свойств «data.properties» в кодировке UTF-8:
# # Параметры сервера SMTP # company=Рога и копыта manager=Остап Бендер
import java.io.Reader; import java.io.IOException; import java.io.InputStream; import java.io.FileInputStream; import java.io.InputStreamReader; import java.util.Properties; public class Main < public static void main(String[] args) < try < InputStream is; is = new FileInputStream("data.properties"); if (is != null) < Reader reader; reader = new InputStreamReader(is, "UTF-8"); Properties props = new Properties(); props.load(reader); System.out.println ( props.getProperty ("company") + ", " props.getProperty ("manager")); is.close(); >> catch (IOException e) < e.printStackTrace(); >> >
Запись в файл FileOutputStream
Класс FileOutputStream, является производным от класса OutputStream, поэтому наследует всю его функциональность.
Пример записи строки в файл:
import java.io.FileOutputStream; public class FilesApp < public static void main(String[] args) < String text = "Hello world!"; // строка для записи try < FileOutputStream fos; fos=new FileOutputStream("C:\\test_dir\\test.txt"); // перевод строки в байты byte[] buffer = text.getBytes(); fos.write(buffer, 0, buffer.length); >catch(IOException e) < System.out.println(e.getMessage()); >> >
Для создания объекта FileOutputStream используется конструктор, принимающий в качестве параметра путь к файлу для записи. Для записи строки ее сначала переводим в массив байт и с помощью метода write строка записывается в файл. Необязательно записывать весь массив байтов. Используя перегрузку метода write(), можно записать и одиночный байт:
fos.write(buffer[0]); // запись только первого байта
Пример перезаписи содержимого из одного файла в другой:
import java.io.FileInputStream; import java.io.FileOutputStream; public class FilesApp < public static void main(String[] args) < try < FileInputStream fis; FileOutputStream fos; fis=new FileInputStream("C:\\test_dir\\test.txt"); fos=new FileOutputStream("C:\\test_dir\\new.txt"); byte[] buffer = new byte[fis.available()]; // считываем буфер fis.read(buffer, 0, buffer.length); // записываем из буфера в файл fos.write(buffer, 0, buffer.length); fis.close(); fos.close(); >catch(IOException e) < System.out.println(e.getMessage()); >> >
Класс FileOutputStream предназначен прежде всего для записи двоичных файлов. Его можно использовать для работы с текстовыми файлами, но все же для этой задачи больше подходят другие классы.
Creating and Reading Directories
Some of the methods previously discussed, such as delete , work on files, links and directories. But how do you list all the directories at the top of a file system? How do you list the contents of a directory or create a directory?
This section covers the following functionality specific to directories:
Listing a File System’s Root Directories
You can list all the root directories for a file system by using the FileSystem.getRootDirectories method. This method returns an Iterable , which enables you to use the enhanced for statement to iterate over all the root directories.
The following code snippet prints the root directories for the default file system:
Iterable dirs = FileSystems.getDefault().getRootDirectories(); for (Path name: dirs)
Creating a Directory
You can create a new directory by using the createDirectory(Path, FileAttribute) method. If you don’t specify any FileAttributes , the new directory will have default attributes. For example:
Path dir = . ; Files.createDirectory(path);
The following code snippet creates a new directory on a POSIX file system that has specific permissions:
Set perms = PosixFilePermissions.fromString("rwxr-x---"); FileAttributeattr = PosixFilePermissions.asFileAttribute(perms); Files.createDirectory(file, attr);
To create a directory several levels deep when one or more of the parent directories might not yet exist, you can use the convenience method, createDirectories(Path, FileAttribute) . As with the createDirectory(Path, FileAttribute) method, you can specify an optional set of initial file attributes. The following code snippet uses default attributes:
Files.createDirectories(Paths.get("foo/bar/test"));
The directories are created, as needed, from the top down. In the foo/bar/test example, if the foo directory does not exist, it is created. Next, the bar directory is created, if needed, and, finally, the test directory is created.
It is possible for this method to fail after creating some, but not all, of the parent directories.
Creating a Temporary Directory
You can create a temporary directory using one of createTempDirectory methods:
The first method allows the code to specify a location for the temporary directory and the second method creates a new directory in the default temporary-file directory.
Listing a Directory’s Contents
You can list all the contents of a directory by using the newDirectoryStream(Path) method. This method returns an object that implements the DirectoryStream interface. The class that implements the DirectoryStream interface also implements Iterable , so you can iterate through the directory stream, reading all of the objects. This approach scales well to very large directories.
Remember: The returned DirectoryStream is a stream. If you are not using a try- with-resources statement, don’t forget to close the stream in the finally block. The try- with-resources statement takes care of this for you.
The following code snippet shows how to print the contents of a directory:
Path dir = . ; try (DirectoryStream stream = Files.newDirectoryStream(dir)) < for (Path file: stream) < System.out.println(file.getFileName()); >> catch (IOException | DirectoryIteratorException x) < // IOException can never be thrown by the iteration. // In this snippet, it can only be thrown by newDirectoryStream. System.err.println(x); >
The Path objects returned by the iterator are the names of the entries resolved against the directory. So, if you are listing the contents of the /tmp directory, the entries are returned with the form /tmp/a , /tmp/b , and so on.
This method returns the entire contents of a directory: files, links, subdirectories, and hidden files. If you want to be more selective about the contents that are retrieved, you can use one of the other newDirectoryStream methods, as described later in this page.
Note that if there is an exception during directory iteration then DirectoryIteratorException is thrown with the IOException as the cause. Iterator methods cannot throw exception exceptions.
Filtering a Directory Listing By Using Globbing
If you want to fetch only files and subdirectories where each name matches a particular pattern, you can do so by using the newDirectoryStream(Path, String) method, which provides a built-in glob filter. If you are not familiar with glob syntax, see What Is a Glob?
For example, the following code snippet lists files relating to Java: .class, .java, and .jar files.:
Path dir = . ; try (DirectoryStream stream = Files.newDirectoryStream(dir, "*.")) < for (Path entry: stream) < System.out.println(entry.getFileName()); >> catch (IOException x) < // IOException can never be thrown by the iteration. // In this snippet, it can // only be thrown by newDirectoryStream. System.err.println(x); >
Writing Your Own Directory Filter
Perhaps you want to filter the contents of a directory based on some condition other than pattern matching. You can create your own filter by implementing the DirectoryStream.Filter interface. This interface consists of one method, accept , which determines whether a file fulfills the search requirement.
For example, the following code snippet implements a filter that retrieves only directories:
DirectoryStream.Filter filter = newDirectoryStream.Filter() < public boolean accept(Path file) throws IOException < try < return (Files.isDirectory(path)); >catch (IOException x) < // Failed to determine if it's a directory. System.err.println(x); return false; >> >;
Once the filter has been created, it can be invoked by using the newDirectoryStream(Path, DirectoryStream.Filter) method. The following code snippet uses the isDirectory filter to print only the directory’s subdirectories to standard output:
Path dir = . ; try (DirectoryStream stream = Files.newDirectoryStream(dir, filter)) < for (Path entry: stream) < System.out.println(entry.getFileName()); >> catch (IOException x)
This method is used to filter a single directory only. However, if you want to find all the subdirectories in a file tree, you would use the mechanism for Walking the File Tree.