Java windows path to linux path

I have a path in windows as: C:\Users\Sneha\.netbeans\5.5.1\tomcat55.properties How can we convert the above path to Linux path. what does .netbeans and tomcat55.properties path means. Any h...

I have a path in windows as:

C:\Users\Sneha\.netbeans\5.5.1\tomcat55.properties

How can we convert the above path to Linux path. what does .netbeans and tomcat55.properties path means.
Any help would be appreciated.

asked Jul 6, 2016 at 7:02

SnehaT's user avatar

4

you should read this webpage to understand difference between file system in linux and windows.

to convert that windows path to linux path, you must know that names of directories and files are case sensitive in linux,

then except using C:\Users\Sneha use this method in java to get current user path in any machine(windows, linux and etc.)

String user_dir = System.getProperty("user.home");

then in linux, path contains only forward slash /. not backward slash .

so the path you said

C:UsersSneha.netbeans5.5.1tomcat55.properties

will be

/home/Sneha/.netbeans/5.5.1/tomcat55.properties

also

  • .netbeans is a folder,
  • tomcat55.properties is a file.

answered Jul 6, 2016 at 8:53

Rahmat Waisi's user avatar

Rahmat WaisiRahmat Waisi

1,2551 gold badge16 silver badges35 bronze badges

Convert windows path to unix in java
2016-11-22 08:00

File separator is «/» on UNIX and «» on Windows. Using FilenameUtils convert path between windows and UNIX is easily. FilenameUtils.separatorsToSystem method can help you to use correct separator.

public static void main(String[] args) {
    String unixPath = "/test/linux/path";
    String windowsPath = "\test\windows\path";
    System.out.println(FilenameUtils.separatorsToWindows(unixPath));
    System.out.println(FilenameUtils.separatorsToUnix(windowsPath));
    System.out.println(FilenameUtils.separatorsToSystem(windowsPath));
}

the pom file like following.

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
</dependency>

So for example say I had it so that all of my files will be transferred from a windows machine to a unix machine as such: C:testmyFile.txt to {somewhere}/test/myFile.txt (drive letter is irrelevant at this point).

Currently, our utility library that we wrote ourselves provides a method that does a simple replace of all back slashes with forward slashes:

public String normalizePath(String path) {
   return path.replaceAll("\", "/");
}

Slashes are reserved and cannot be part of a file name, so the directory structure should be preserved. However, I’m not sure if there are other complications between windows and unix paths that I may need to worry about (eg: non-ascii names, etc)

asked Jun 16, 2014 at 16:26

MxLDevs's user avatar

MxLDevsMxLDevs

7793 gold badges10 silver badges15 bronze badges

15

Yes, if you only do the replacement on Windows, and turn it off when running on other systems.

Doing the replacement on Unix-like systems is wrong because is a valid character in a file or directory name on Unix-like platforms. On these platforms, only NUL and / are forbidden in file and directory names.

Also, some Windows API functions (mostly the lower level ones) do not allow the use of forward slashes ― backslashes must be used with them.

Edit: It turns out that there are some special file systems on Windows on which / and NUL are valid characters, such as the Registry (available at \?GLOBALROOTRegistry from a Windows API perspective, or Registry from the Native API perspective). In the Named Pipe File System (usually mounted at ??pipe), all characters (including /, , and even NUL) are valid. So in general, not only is it not valid to replace / with on Windows, it is not valid to assume that every Windows file can be accessed using the Windows API! To reliably access arbitrary files, one must use the Native API (NtCreateFile and friends). NtCreateFile also exposes an equivalent of openat(2), which isn’t exposed via the Windows API.

answered Jul 23, 2014 at 0:41

Demi's user avatar

DemiDemi

8167 silver badges18 bronze badges

Yes, but this whole thing is a moot point. Java seamlessly converts forward slashes to back slashes on Windows. You can simply use forward slashes for all paths that are hard-coded or stored in configuration and it will work for both platforms.

Personally, I always use the forward slash even on Windows because it is not the escape character. Whether the raw path is in code or externalized in a properties file, I encode it the same way.

Try it! This will work in Windows. Obviously, change the actual path to something that exists and your user has permission to read.

File f = new File("c:/some/path/file.txt");
if (!f.canRead()) {
  System.out.println("Uh oh, Snowman was wrong!");
}

Bonus: you can even mix slashes in the same path!

File f = new File("c:/some\path/file.txt");
if (!f.canRead()) {
  System.out.println("Uh oh, Snowman was wrong again!");
}

answered Aug 22, 2014 at 1:26

6

Another complication on Windows is that it also supports UNC notation as well as the traditional drive letters.

A file on a remote file server can be accessed as \serversharenamepathfilename.

answered Aug 22, 2014 at 10:39

Simon B's user avatar

Simon BSimon B

8,9164 gold badges26 silver badges32 bronze badges

1

No. There are far more things to think about than just the path separator (the » vs /» thing). As Rob Y mentions, there is how spaces are handled, and their high frequency in Windows usage. There are different illegal characters in the two environments. There is Unix’s willingness to allow almost anything when escaped by a leading «». There is Windows use of ‘»‘ to deal with embedded spaces. There is Windows’ use of UCS-16 and Unix’s use of ASCII or UTF-8.

etc., etc., etc.

But, for lots of applications that can put constraints on the pathnames they need to manipulate, you actually can do it just the way you suggest. And it will work in at least a large number of the cases, just not all of them.

answered Aug 22, 2014 at 1:02

Ross Patterson's user avatar

1

Every Microsoft operating system, starting with MS-DOS, has understood, at the kernel level, both forward slashes and backslashes.

Therefore, on Windows, you can convert between them freely; both have equal status as reserved separators. In any valid path, you can replace backslashes with slashes and vice versa, without changing its meaning, as far as the kernel is concerned.

In early versions of DOS, Microsoft’s command.com interpreter made it a configurable preference which slash was used to display and parse paths. That was eventually removed.

Some user-space programs in Windows such as, oh, the Windows shell (explorer.exe) do not like forward slashes. That’s just shoddy programming in those programs.

answered Jul 8, 2016 at 3:16

Kaz's user avatar

KazKaz

3,5241 gold badge18 silver badges30 bronze badges

2

Цикл статей «Учебник Java 8».

Следующая статья — «Java 8 многопоточность».
Предыдущая статья — «Java 8 сериализация».

Содержание

java.nio.file.Path

Что такое Glob?

java.nio.file.Files

— Проверка существования файла или каталога

— Проверка прав доступа к файлу или каталогу

— Один и тот же файл

— Удаление файла или каталога

— Копирование файла или каталога

— Перемещение файла или каталога

— Управление метаданными

— Чтение, запись и создание файлов

— — OpenOption

— — Наиболее часто используемые методы для небольших файлов

— — Буферизированный ввод и вывод в текстовые файлы

— — Небуферезированный ввод и вывод

— — Создание файлов

— — Создание временных файлов

— Файлы с произвольным доступом

— Создание и чтение каталогов

— — Перечисление корневых каталогов файловой системы

— — Создание каталога

— — Создание временного каталога

— — Перечисление содержимого каталога

— Символические и другие ссылки

— — Создание символических ссылок

— — Создание жёстких ссылок

— — Определение символической ссылки

— — Нахождение цели ссылки

— Обход дерева файлов

— — Интерфейс java.nio.file.FileVisitor

— — Запуск процесса обхода дерева файлов

— — Размышления о FileVisitor

— — Управление обходом дерева файлов

— — Примеры

— Поиск файлов

Подписываемся на изменения в каталоге

— Обработка событий

java.nio.file.Path

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

Экземпляры
Path  отражают путь в конкретной платформе (например
/home/jho/foo  для Linux или
C:homejhofoo  для Windows). Экземпляры
Path  зависят от платформы. Нельзя сравнивать
Path  из Linux с путём из Windows, даже если структура их каталогов одинаковая, и оба этих экземпляра указывают на один и тот же относительный файл.

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

Создавать экземпляры
Path  можно разными способами.

Можно использовать методы
java.nio.file.Paths.get() :

public static Path get(String first,

                       String... more)

public static Path get(URI uri)

Примеры:

Path p1 = Paths.get(«/tmp/foo»);

Path p2 = Paths.get(args[0]);

Path p3 = Paths.get(URI.create(«file:///Users/joe/FileTest.java»));

Эти методы являются сокращённой формой для следующего кода:

Path p4 = java.nio.file.FileSystems.getDefault().getPath(«/users/sally»);

Можно рассматривать
Path  как класс, сохраняющий имена каталогов в пути и имя файла в виде последовательности. Наивысший (ближний к корневому) элемент находится по индексу 0, самый нижний элемент находится по индексу
n1 , где
n  — количество элементов в пути.

Получить конкретный элемент пути можно с помощью метода
getName() :

String element0 = path.getName(0)

// Для пути /homme/jho/foo (Linux) вернётся home

// Для пути C:homejoefoo (Windows) вернётся home.

Узнать количество элементов в пути можно с помощью метода
getNameCount():

int nameCount = path.getNameCount();

// Для /home/jho/foo (Linux) вернёт 3

// Для C:homejhofoo (Windows) вернёт 3

Можно получить путь родительской директории с помощью метода
getParent() :

Path parentPath = path.getParent();

// Для /home/jho/foo (Linux) вернётся /home/jho

// Для C:homejhofoo Windows вернётся C:homejho

// Вернёт null, если родительского элемента нет.

Можно получить корень пути с помощью метода
getRoot() :

Path rootPath = path.getRoot();

// Для /home/jho/foo (Linux) вернёт /

// Для C:homejhofoo (Windos) вернёт C:

// Вернёт null, если путь относительный и корня нет.

С помощью метода
toString()  можно получить путь в виде строки:

String str1 = path.toString()

// Вернёт строку «/home/jho/foo» для пути /home/jho/foo (Linux).

// Вернёт строку «C:homejhofoo» для пути C:homejhofoo (Windows).

Многие файловые системы используют символ точки «.» для обозначения текущего каталога и две точки «..» для обозначения родительского каталога. Например:

/home/./jho/foo

/home/sandy/../jho/foo

Метод
normalize()  удаляет все подобные элементы и приводит к нормализованному пути
/home/jho/foo/. Этот метод не проверяет файловую систему. Это чисто синтетическая операция, работающая с элементами
Path. Если
sandy  является символической ссылкой, то удаление
sandy/..  может привести к тому, что
Path  больше не указывает на предыдущий файл.

Если вам нужно преобразовать
Path  к строке, с помощью которой можно открыть  файл в браузере, то используйте метод
toUri():

Path p1 = Paths.get(«/home/logfile»);

// Result is file:///home/logfile

System.out.format(«%s%n», p1.toUri());

Метод
toAbsolutePath()  преобразует путь к абсолютному. Способ преобразования зависит от системы.  Если переданный путь уже является абсолютным, то возвращается тот же самый объект
Path.

Метод
toRealPath()  возвращает реальный путь существующего файла. В качестве параметра в метод можно передать константу перечисления
java.nio.file.LinkOption  с единственным возможным значением
NOFOLLOW_LINKS . Метод бросает исключение, если файл не существует, либо к нему нет доступа. Этот метод убирает все элементы «.» и «..» и возвращает всегда абсолютный путь.

try {

    Path fp = path.toRealPath();

} catch (NoSuchFileException x) {

    System.err.format(«%s: no such» + » file or directory%n», path);

    // Logic for case when file doesn’t exist.

} catch (IOException x) {

    System.err.format(«%s%n», x);

    // Logic for other sort of file error.

}

Можно объединять пути с помощью метода
resolve() , в который передаётся часть пути, которую нужно добавить к исходному пути:

// Solaris

Path p1 = Paths.get(«/home/joe/foo»);

// Result is /home/joe/foo/bar

System.out.format(«%s%n», p1.resolve(«bar»));

Или для Windows:

// Microsoft Windows

Path p1 = Paths.get(«C:\home\joe\foo»);

// Result is C:homejoefoobar

System.out.format(«%s%n», p1.resolve(«bar»));

С помощью метода
relativize()  можно создать относительный путь от одного пути к другому:

Path p1 = Paths.get(«jho»);

Path p2 = Paths.get(«sandy»);

// Так как нет другой информации, то считается, что

// jho и sandy находятся в одном каталоге.

// Result is ../sandy

Path p1_to_p2 = p1.relativize(p2);

// Result is ../jho

Path p2_to_p1 = p2.relativize(p1);

Слегка усложнённый пример:

Path p1 = Paths.get(«home»);

Path p3 = Paths.get(«home/sandy/bar»);

// Result is sandy/bar

Path p1_to_p3 = p1.relativize(p3);

// Result is ../..

Path p3_to_p1 = p3.relativize(p1);

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

Path  поддерживает метод
equals(), что позволяет сравнивать пути. Так же есть методы
startsWith(Path other) ,
startsWith(String other) ,
endsWith(Path other) ,
endsWith(String other) , позволяющие проверять начало и конец пути на совпадение с указанной строкой или частью пути. Path реализует интерфейс Comparable, что позволяет сортировать строки.

Что такое Glob?

Некоторые методы класса
java.nio.file.Files  принимают аргумент glob. Шаблон glob использует следующие правила:

Символ «*» обозначает любое количество символов (включая отсутствие символов).

Две снежинки «**» работают так же, как и одна, но переходят за границы каталогов.

Символ вопроса «?» обозначает ровно один символ.

Фигурные скобки указывают коллекцию паттернов. Например
{sun,moon,starts}  совпадает с
«sun» ,
«moon»  или
«starts».
{temp*, tmp*}  совпадает со всеми строками, начинающимися с
«temp»  или
«tmp».

Квадратные скобки позволяют указать набор символов либо диапазон символов:

[aeiou] обозначает любую строчную гласную.

[0-9] обозначает любую цифру

[A-Z] обозначает любую прописную букву.

[a-z,A-Z] обозначает любую строчную или прописную букву.

Внутри квадратных скобок «*», «?» и «/» обозначают самих себя.

java.nio.file.Files

Проверка существования файла или каталога

Проверить существование пути
Path  можно с помощью методов:

public static boolean exists(Path path,

                             LinkOption... options)

public static boolean notExists(Path path,

                                LinkOption... options)

Если передать константу
LinkOption.NOFOLLOW_LINKS , то метод не будет проходить по символическим ссылкам. Если оба метода
exists()  и
notExists()  возвращают
false , то существование файла не может быть проверено (например нет доступа).

Проверка прав доступа к файлу или каталогу

Проверка доступа к файлу осуществляется с помощью методов:

// Проверяет, что файл доступен для чтения

public static boolean isReadable(Path path)

// Проверяет, что файл доступен для записи

public static boolean isWritable(Path path)

// Проверяет, что файл доступен для выполнения

public static boolean isExecutable(Path path)

Один и тот же файл

Можно проверить, что два пути указывают на один и тот же файл на одной и той же файловой системе:

public static boolean isSameFile(Path path,

                                 Path path2)

                          throws IOException

Удаление файла или каталога

Метод
delete(Path)  удаляет файл или бросает исключение, если удалить файл не удалось. Можно удалять каталог, но только если он пустой.

try {

    Files.delete(path);

} catch (NoSuchFileException x) {

    System.err.format(«%s: no such» + » file or directory%n», path);

} catch (DirectoryNotEmptyException x) {

    System.err.format(«%s not empty%n», path);

} catch (IOException x) {

    // File permission problems are caught here.

    System.err.println(x);

}

Метод

public static boolean deleteIfExists(Path path)

                              throws IOExceptio

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

Копирование файла или каталога

Можно копировать файл или каталог с помощью метода
copy(Path, Path, CopyOption...) , но имейте в виду, что файлы внутри каталога не копируются этим методом. Метод принимает константы
CopyOption:

StandardCopyOption.REPLACE_EXISTING заменять существующие файлы.

StandardCopyOption.COPY_ATTRIBUTES копирует атрибуты файла.

LinkOption.NOFOLLOW_LINKS не переходить по символическим ссылкам.

Перемещение файла или каталога

Можно переместить файл или каталог с помощью метода
move(Path, Path, CopyOption...) . Можно перемещать пустые каталоги. Возможность перемещения каталогов с содержимым зависит от платформы. Метод принимает
CopyOption:

  • StandardCopyOption.REPLACE_EXISTING заменяет существующий файл, если он существует.
  • StandardCopyOption.ATOMIC_MOVE попытка осуществить перемещение файла как единую атомарную операцию. Все остальные опции игнорируются.

Управление метаданными

Метаданные файлов это: размер, дата создания, дата последнего изменения, владелец, права доступа и прочее.

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

Методы для работы с метаданными:

public static long size(Path path)

                 throws IOException

Возвращает размер файла в байтах.

public static boolean isDirectory(Path path,

                                  LinkOption... options)

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

public static boolean isRegularFile(Path path,

                                    LinkOption... options)

Возвращает
true, если
path  указывает на обычный файл. Можно передать
LinkOption.NOFOLLOW_LINKS, чтобы метод не переходил по символическим ссылкам.

public static boolean isSymbolicLink(Path path)

Возвращает
true , если
path  указывает на символическую ссылку.

public static boolean isHidden(Path path)

                        throws IOException

Возвращает
true, если файл является скрытым. Для Linux файл является скрытым, если его имя начинается с точки. Для Windows файл является скрытым, если установлен соответствующий атрибут.

public static FileTime getLastModifiedTime(Path path,

                                           LinkOption... options)

                                    throws IOException

Возвращает FileTime с датой последнего изменения файла. Можно передать
LinkOption.NOFOLLOW_LINKS , чтобы метод не переходил по символическим ссылкам.

public static Path setLastModifiedTime(Path path,

                                       FileTime time)

                                throws IOException

Устанавливает дату последнего изменения файла. Смотрите описание класса FileTime в документации Oracle.

public static UserPrincipal getOwner(Path path,

                                     LinkOption... options)

                              throws IOException

Возвращает владельца файла. Можно использовать метод
String getName()  у возвращённого объекта, чтобы получить имя пользователя.

public static Path setOwner(Path path,

                            UserPrincipal owner)

                     throws IOException

Меняет владельца файла.

Различные файловые системы имеют различные атрибуты файлов. Можно считывать группы атрибутов:

  • BasicFileAttributeView — базовые атрибуты файлов, которые должны поддерживаться всеми реализациями файловых систем.
  • DosFileAttributeView — расширяет стандартные атрибуты 4 битам (скрытый, архивный, только чтение, системный).
  • PosixFileAttributeView — расширяет базовые атрибуты атрибутами системы Linux.
  • FileOwnerAttributeView — поддерживается всеми файловыми системами, которые поддерживают владельцев файлов.
  • AclFileAttributeView — права доступа к файлу, которые реализованы в Windows.
  • UserDefinedFileAttributeView — пользовательские метаданные.

Получение конкретной группы атрибутов происходит с помощью метода

public static <V extends FileAttributeView> V getFileAttributeView(Path path,

                                                                   Class<V> type,

                                                                   LinkOption... options)

Пример:

Path path = ...

AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);

if (view != null) {

    List<AclEntry> acl = view.getAcl();

    // …

}

Работа с конкретными группами метаданных/атрибутов очень зависит от платформы. Вам вряд ли когда-нибудь придётся столкнуться с этим. Но если интересно, то рекомендую рассмотреть мой проект niofilecommander, который использует все группы атрибутов, описанные здесь.

Чтение, запись и создание файлов

OpenOption

Многие методы, описанные в этом разделе используют
OpenOption  в качестве своих параметров. В этом случае в метод можно передавать следующие значения:

  • LinkOption.NOFOLLOW_LINKS  не переходить по символическим ссылкам.
  • StandardOpenOption.APPEND  если файл открыт для записи, то байты будут добавляться в конец файла, а не в начало.
  • StandardOpenOption.CREATE  создавать новый файл, если его нет.
  • StandardOpenOption.CREATE_NEW  создавать новый файл. Если файл уже существует, то происходит ошибка.
  • StandardOpenOption.DELETE_ON_CLOSE  удалять файл при закрытии.
  • StandardOpenOption.DSYNC  каждое обновление содержимого файла синхронного пишется на устройство хранения (жёсткий диск).
  • StandardOpenOption.READ  открыть для чтения
  • StandardOpenOption.SPARCE  sparce file
  • StandardOpenOption.SYNC  каждое обновление содержимого файла или метаданных синхронно пишется на устройство чтения (жёсткий диск).
  • StandardOpenOption.TRUNCATE_EXISTING  если файл уже существует и открывается для записи, то его длина устанавливается в 0.
  • StandardOpenOption.WRITE  открывает файл на запись.

Наиболее часто используемые методы для небольших файлов

public static byte[] readAllBytes(Path path)

                           throws IOException

Читает содержимое файла и возвращает его в массиве байт.

public static List<String> readAllLines(Path path,

                                        Charset cs)

                                 throws IOException

Читает содержимое текстового файла и возвращает его в виде списка строк.

public static Path write(Path path,

                         byte[] bytes,

                         OpenOption... options)

                  throws IOException

Записывает байты в файл.

public static Path write(Path path,

                         Iterable<? extends CharSequence> lines,

                         Charset cs,

                         OpenOption... options)

                  throws IOException

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

Буферизированный ввод и вывод в текстовые файлы

public static BufferedReader newBufferedReader(Path path,

                                               Charset cs)

                                        throws IOException

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

public static BufferedWriter newBufferedWriter(Path path,

                                               Charset cs,

                                               OpenOption... options)

                                        throws IOException

Открывает или создаёт файл для записи. Возвращаемый
BufferedWriter  может быть использован для записи в файл. Если
OpenOption  не переданы, то используются опции:
CREATE ,
TRUNCATE_EXISTING ,
WRITE.

Небуферезированный ввод и вывод

public static InputStream newInputStream(Path path,

                                         OpenOption... options)

                                  throws IOException

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

public static OutputStream newOutputStream(Path path,

                                           OpenOption... options)

                                    throws IOException

Возвращает поток, который можно использовать для записи байт в файл. Если
OpenOption  не переданы, то используются опции:
CREATE,
TRUNCATE_EXISTING,
WRITE.

Создание файлов

public static Path createFile(Path path,

                              FileAttribute<?>... attrs)

                       throws IOException

Создаёт новый и пустой файл. Бросает исключение, если файл уже существует.

Создание временных файлов

public static Path createTempFile(Path dir,

                                  String prefix,

                                  String suffix,

                                  FileAttribute<?>... attrs)

                           throws IOException

Создаёт временный файл в указанном каталоге. Является только частью работы с временными файлами. Вы можете использовать метод
File.deleteOnExit(), для того чтобы каталог удалялся автоматически.

public static Path createTempFile(String prefix,

                                  String suffix,

                                  FileAttribute<?>... attrs)

                           throws IOException

Создаёт временный файл в специальном каталоге для временных файлов. Является только частью работы с временными файлами. Вы можете использовать метод
File.deleteOnExit(), для того чтобы каталог удалялся автоматически.

Файлы с произвольным доступом

Файл можно открыть одновременно для чтения и записи и с возможностью перемещения текущей позиции в любое место файла. Подобная функциональность реализуется с помощью интерфейса
java.nio.channels.SeekableByteChannel.

Получить экземпляр класса, реализующего интерфейс
SeekableByteChannel, можно с помощью статического метода из класса
Files:

public static SeekableByteChannel newByteChannel(Path path,

                                                 OpenOption... options)

                                          throws IOException

либо:

public static SeekableByteChannel newByteChannel(Path path,

                                                 Set<? extends OpenOption> options,

                                                 FileAttribute<?>... attrs)

                                          throws IOException

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

String s = «I was here!n»;

byte data[] = s.getBytes();

ByteBuffer out = ByteBuffer.wrap(data);

ByteBuffer copy = ByteBuffer.allocate(12);

try (FileChannel fc = (FileChannel.open(file, READ, WRITE))) {

    // Читаем первые 12

    // байт из файла.

    int nread;

    do {

        nread = fc.read(copy);

    } while (nread != 1 && copy.hasRemaining());

    // Пишем «I was here!» в начало файла.

    fc.position(0);

    while (out.hasRemaining())

        fc.write(out);

    out.rewind();

    // Перемещаемся в конец файла. Копируем первые 12 байт в

    // конец файла.  Пишем «I was here!» снова.

    long length = fc.size();

    fc.position(length1);

    copy.flip();

    while (copy.hasRemaining())

        fc.write(copy);

    while (out.hasRemaining())

        fc.write(out);

} catch (IOException x) {

    System.out.println(«I/O Exception: « + x);

}

Создание и чтение каталогов

Перечисление корневых каталогов файловой системы

Для этого используется специальный метод класса
FileSystem :

public abstract Iterable<Path> getRootDirectories()

Пример:

Iterable<Path> dirs = FileSystems.getDefault().getRootDirectories();

for (Path name: dirs) {

    System.err.println(name);

}

Создание каталога

Метод класса
Files :

public static Path createDirectory(Path dir,

                                   FileAttribute<?>... attrs)

                            throws IOException

Создаёт каталог.

public static Path createDirectories(Path dir,

                                     FileAttribute<?>... attrs)

                              throws IOException

Создаёт каталог вместе со всеми родительскими каталогами, которых ещё нет.

Создание временного каталога

public static Path createTempDirectory(Path dir,

                                       String prefix,

                                       FileAttribute<?>... attrs)

                                throws IOException

Создаёт временный каталог. Как и методы
createTempFile  является только частью работы с временными файлами. Вы можете использовать метод
File.deleteOnExit(), для того чтобы каталог удалялся автоматически.

public static Path createTempDirectory(String prefix,

                                       FileAttribute<?>... attrs)

                                throws IOException

Создаёт временный каталог в специалном каталоге для временных файлов. Как и методы
createTempFile  является только частью работы с временными файлами. Вы можете использовать метод
File.deleteOnExit(), для того чтобы каталог удалялся автоматически.

Перечисление содержимого каталога

public static DirectoryStream<Path> newDirectoryStream(Path dir)

                                                throws IOException

Возвращает поток, который позволяет пройтись по всем элементам каталога.

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

Path dir = ...;

try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {

    for (Path file: stream) {

        System.out.println(file.getFileName());

    }

} catch (IOException | DirectoryIteratorException x) {

    // IOException не может броситься во время итерации.

    // В этом куске кода оно может броситься только

    // методом newDirectoryStream.

    System.err.println(x);

}

public static DirectoryStream<Path> newDirectoryStream(Path dir,

                                                       String glob)

                                                throws IOException

Позволяет посмотреть элементы каталога, названия которых удовлетворяют переданному шаблону Glob.

Например, следующий код возвращает список файлов с расширениями «.class», «.java», «.jar»:

Path dir = ...;

try (DirectoryStream<Path> stream =

     Files.newDirectoryStream(dir, «*.{java,class,jar}»)) {

    for (Path entry: stream) {

        System.out.println(entry.getFileName());

    }

} catch (IOException x) {

    // IOException никогда не бросится во время итерации.

    // В этом куске кода оно может броситься только

    // методом newDirectoryStream

    System.err.println(x);

}

Можно написать свой собственный фильтр для содержимого каталога. Например, этот фильтр будет возвращать только каталоги:

DirectoryStream.Filter<Path> filter =

    newDirectoryStream.Filter<Path>() {

    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;

        }

    }

};

Фильтр применяется методом:

public static DirectoryStream<Path> newDirectoryStream(Path dir,

                                                       DirectoryStream.Filter<? super Path> filter)

                                                throws IOException

Пример:

Path dir = ...;

try (DirectoryStream<Path>

                       stream = Files.newDirectoryStream(dir, filter)) {

    for (Path entry: stream) {

        System.out.println(entry.getFileName());

    }

} catch (IOException x) {

    System.err.println(x);

}

Символические и другие ссылки

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

Ссылки бывают символическими и жёсткими. Жёсткие ссылки имеют больше ограничений, чем символические:

  • Цель, на которую указывает жёсткая ссылка, должна существовать.
  • Жёсткие ссылки обычно не могут указывать на каталоги.
  • Жёсткие ссылки не могут указывать на другой раздел или том и не могут указывать на другую файловую систему.
  • Жёсткие ссылки выглядят и ведут себя так, как обычный файл, поэтому их может быть трудно обнаружить.
  • Жёсткая ссылка для всех целей и действий является той же сущностью, что и исходный файл. Они имеют те же самые права доступа, временные метки и т. д.

Из-за таких ограничений жёсткие ссылки не так часто используются, как символические ссылки.

Создание символических ссылок

Если ваша файловая система поддерживает символические ссылки, то вы можете создавать их с помощью метода класса
Files:

public static Path createSymbolicLink(Path link,

                                      Path target,

                                      FileAttribute<?>... attrs)

                               throws IOException

Этот метод создаёт символическую ссылку по пути
link, указывающую на
target. Параметр
attrs  позволяет задать атрибуты ссылки.

Создание жёстких ссылок

public static Path createLink(Path link,

                              Path existing)

                       throws IOException

Создаёт жёсткую ссылку по пути
link, указывающую на
existing.

Определение символической ссылки

public static boolean isSymbolicLink(Path path)

Этот метод класса
Files  возвращает
true, если файл является символической ссылкой.

Нахождение цели ссылки

public static Path readSymbolicLink(Path link)

                             throws IOException

Этот метод класса
Files  возвращает путь, на который указывает символическая ссылка. Если link не является ссылкой, то бросается исключение
java.nio.file.NotLinkException.

Обход дерева файлов

Интерфейс java.nio.file.FileVisitor

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

  • preVisitDirectory — вызывается перед посещением элементов каталога.
  • postVisitDirectory — вызывается после посещения всех элементов каталога.
  • visitFile — вызывается при посещении файла. В метод передаются
    BasicFileAttributes.
  • visitFileFailed — вызывается в случае, когда не удаётся получить доступ к файлу.

Если вам не нужны все эти четыре метода, то вы можете вместо реализации интерфейса
FileVisitor  унаследоваться от
java.nio.file.SimpleFileVisitor. Этот класс реализует
FileVisitor  и посещает все файлы в дереве, бросая исключение
IOException  при возникновении ошибки. Вы можете отнаследоваться от этого класса и реализовать только те методы, которые вам нужны.

Пример реализации
SimpleFileVisitor:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

import static java.nio.file.FileVisitResult.*;

public static class PrintFiles

    extends SimpleFileVisitor<Path> {

    // Выводит в консоль информацию о

    // каждом типе файлов.

    @Override

    public FileVisitResult visitFile(Path file,

                                   BasicFileAttributes attr) {

        if (attr.isSymbolicLink()) {

            System.out.format(«Symbolic link: %s «, file);

        } else if (attr.isRegularFile()) {

            System.out.format(«Regular file: %s «, file);

        } else {

            System.out.format(«Other: %s «, file);

        }

        System.out.println(«(« + attr.size() + «bytes)»);

        return CONTINUE;

    }

    // Пишет в консоль каждый посещаяемый каталог

    @Override

    public FileVisitResult postVisitDirectory(Path dir,

                                          IOException exc) {

        System.out.format(«Directory: %s%n», dir);

        return CONTINUE;

    }

    // Если возникла какая-нибудь ошибка при доступе к файлу,

    // то выводим эту ошибку.

    // Если вы не переопределите этот метод, и возникнет

    // ошибка, то бросится исключение IOException

    @Override

    public FileVisitResult visitFileFailed(Path file,

                                       IOException exc) {

        System.err.println(exc);

        return CONTINUE;

    }

}

Запуск процесса обхода дерева файлов

public static Path walkFileTree(Path start,

                                FileVisitor<? super Path> visitor)

                         throws IOException

или

public static Path walkFileTree(Path start,

                                Set<FileVisitOption> options,

                                int maxDepth,

                                FileVisitor<? super Path> visitor)

                         throws IOException

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

Пример для нашего
PrintFiles :

Path startingDir = ...;

PrintFiles pf = new PrintFiles();

Files.walkFileTree(startingDir, pf);

Размышления о FileVisitor

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

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

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

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

Если вы пишете поиск файла, то осуществляйте сравнение в
visitFile, если вам нужно находить не только файлы, но и каталоги, то используйте в добавок метод
preVisitDirectory  или
postVisitDirectory.

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

Метод
visitFile  вызывается для файлов. Если вы указали
FOLLOW_LINKS, и ваше дерево файлов имеет циклическую ссылку на родительский каталог, то во время повторение каталога будет сообщено в
visitFileFailed  с помощью исключения
FileSystemLoopException.

Управление обходом дерева файлов

Во время обхода может потребоваться не заходить внутрь какого-либо каталога либо даже прервать обход дерева. Методы
FileVisitor  возвращают
java.nio.file.FileVisitResult, которое является перечислением со следующими константами:

  • FileVisitResult.CONTINUE  — указывает, что обход дерева файлов должен продолжаться. Если метод
    preVisitDirectory  возвращает
    CONTINUE , то каталог посещаяется.
  • FileVisitResult.TERMINATE  — прерывает обход всего дерева файлов.
  • FileVisitResult.SKIP_SUBTREE  — Если
    preVisitDirectory  возвращает это значение, то указанный каталог и его подкаталоги пропускаются.
  • FileVisitResult.SKIP_SIBLINGS  — Если
    preVisitDirectory  возвращает это значение, то указанный каталог не посещается, и
    postVisitDirectory  не вызывается. Если возвращается из
    postVisitDirectory, то остальные каталоги с тем же родительским каталогом пропускаются.

Примеры

Смотрите примеры в niofilecommander.

Поиск файлов

Каждая реализация файловой системы поставляет свою реализацию интерфейса 
java.nio.file.PathMatcher.

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

String pattern = ...;

PathMatcher matcher =

    FileSystems.getDefault().getPathMatcher(«glob:» + pattern);

Строка, которая передаётся в этот метод, указывает какие файлы искать. В этом примере используется синтаксис glob. Можно использовать регулярные выражения, тогда вместо
«glob:»  нужно писать
«regex:».

В дальнейшем этот
matcher  можно использовать при обходе дерева файлов вот так:

if (matcher.matches(filename)) {

    System.out.println(filename);

}

Подписываемся на изменения в каталоге

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

  1. Создаём экземпляр
    WatchService  для файловой системы.
  2. Для каждого каталога, за которым нужно наблюдать, регистрируем наблюдателя (watcher). При регистрации каталога вы указываете события, о которых вам бы хотелось знать. Для каждого каталога вы получаете экземпляр класса
    WatchKey.
  3. Делаем бесконечный цикл на входящих событиях. При возникновении события
    WatchKey  этого каталога получает сигнал и кладётся в очередь наблюдателя.
  4. Получаем
    WatchKey  из очереди. Вы можете получить имя файла из этого ключа.
  5. Получаем каждое событие для ключа (их может быть несколько) и обрабатываем.
  6. Сбрасываем
    WatchKey  и возвращаемся в ожиданию событий.
  7. Закрываем
    WatchServce. Он закрывается при выходе из потоки либо при вызове метода.

Экземпляры
WatchKey  потокобезопасны.

Пример:

import static java.nio.file.StandardWatchEventKinds.*;

...

WatchService watcher = FileSystems.getDefault().newWatchService();

Path dir = ...;

try {

    WatchKey key = dir.register(watcher,

                           ENTRY_CREATE,

                           ENTRY_DELETE,

                           ENTRY_MODIFY);

} catch (IOException x) {

    System.err.println(x);

}

Обработка событий

Сначала мы получаем
WatchKey  с помощью одного из методов
WatchService :

Удаляет из очереди и возвращает следующий
WatchKey  либо
null , если очередь пуста.

WatchKey poll(long timeout,

              TimeUnit unit)

       throws InterruptedException

Удаляет из очереди и возвращает следующий
WatchKey. Ждёт, если нужно, указанное количество времени.

WatchKey take()

       throws InterruptedException

Удаляет из очереди и возвращает следующий
WatchKey. Если очередь пуста, то ждёт до тех пор, пока не появится хоть что-нибудь.

Затем обрабатываются все события  из
WatchKey, которые получаются при вызове его метода:

List<WatchEvent<?>> pollEvents()

Тип события получается с помощью следующего метода
WatchEvent :

WatchEvent.Kind<T> kind()

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

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

Вызываем
reset()  на
WatchKey . Если он вернул
false, то он больше не работает и из цикла можно выходить.

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

 
Цикл статей «Учебник Java 8».

Следующая статья — «Java 8 многопоточность».
Предыдущая статья — «Java 8 сериализация».

Improve Article

Save Article

  • Read
  • Discuss
  • Improve Article

    Save Article

    PATH is an environment variable that is used by Operating System to locate the exe files (.exe) or java binaries ( java or javac command). The path once it is set, cannot be overridden. The PATH variable prevents us from having to write out the entire path to a program on the Command Line Interface every time we run it. Moreover, the path is just a variable that stores a bunch of shortcuts.

    To execute java console-based programs in windows or Linux environments we have to use java and javac commands. The commands java and javac are not known to the operating system as we don’t specify where the executables reside. Hence, we need to specify the path where the executables are located. This is the reason we set the path and specify the path of the bin folder because the bin contains all binary executable files. After setting the path it can load all necessary items in the program including the compiler or interpreter itself. 

    Below is the procedure for setting the path for both Windows and Linux:

    Setting Java Path in Windows

    1. Go to the Search box and type advanced system settings in it. Now click on the View advanced system settings.

    2. Select the Advanced tab and then click environment variables.

    3. In the system, variables click the New button. Now in the edit system variable, type variable name as JAVA_HOME and variable path as the path where the JDK folder is saved and click on OK button Usually the path of the JDK file will be C:Program FilesJavajdk1.8.0_60.

    4. Now in the system variables go to the path and click the edit button.

    5. Click the New button.

    6. Now add the following path: %JAVA_HOME%bin

    Setting Java Path in Linux

    • Open the terminal and enter the following command: 
    sudo nano /etc/environment.
    • A file will be opened and add the following command to that file:
    JAVA_HOME = "YOUR_PATH". 
    • Replace YOUR_PATH with the JDK bin file path.
    • Now restart your computer or virtual machine that you are using (or) reload the file: source /etc/environment
    • You can test the path by executing
     echo $JAVA_HOME
    • If you get the output without any error, then you’ve set the path correctly.
    • If you get any errors, try repeating the procedure again.

    After covering file reading and writing operations in Java, this third part of the series of articles shows how to use the classes File, Path, and Paths to construct file and directory paths – regardless of the operating system.

    If you have already dealt with file operations in Java, you have probably used these classes to pass a filename to one of the read or write operations with new File(), Paths.get() or Path.of().

    Most programmers do not study these classes in much more detail. This is partly because these classes can be confusing even for experienced Java programmers: What is the difference between File.getName() and File.getPath()? What is the difference between File.getAbsolutePath(), File.getCanonicalPath() and Path.normalize()? What is the difference between Paths.get() and Path.of()?

    This article answers the following questions:

    • What is the difference between a filename, a directory name, and a path?
    • How to construct a relative directory or file path independent of the operating system?
    • How to construct an absolute directory or file path independent of the operating system?
    • What changed with the introduction of the NIO.2 File API?
    • What exactly is returned by the File methods getName(), getPath(), getParent(), getParentFile(), getAbsolutePath(), getAbsoluteFile(), getCanonicalPath(), getCanonicalFile()?
    • What is returned by the Path methods getFileName(), getName(int index), getParent(), getRoot(), toAbsolutePath() und normalize()?
    • How to join Path objects with Path.resolve() and Path.resolveSibling()?
    • When to use File and when to use Path? And can I convert the two into each other?

    Basics: Definitions of terms, operating system independence, NIO.2

    What is the difference between filename, directory name, relative path, and absolute path?

    Before we start, we need to agree on terminology. For example, the terms «path» and «directory» are often confused.

    • Filename: the name of a file without a directory and separators, e.g., readme.txt
    • Directory name: the name of a particular directory without parent directory(s), for example, apache-maven-3.6.3 or log
    • Path: the «route» to an object of the file system, i.e., to files and directories. A path can be absolute or relative:
      • An absolute path is always unique and independent of the current position in the file system.
      • A relative path is related to the current position within the file system. It describes how to get from this position to the target. If the target is located in the current directory, the relative path usually equals the file or directory name.

    The following table shows some examples of absolute and relative paths to directories and files – for both Windows and Linux/Mac:

    Linux / Mac Windows
    Absolute path to a directory: /var/log C:Windows
    Absolute path to a file: /var/log/syslog C:Windowsexplorer.exe
    Relative path to a directory: ../../var/log

    (from /home/user to /var/log)

    ..Windows

    (from C:Users to C:Windows)

    Relative path to a file: ../../var/log/syslog

    (from /home/user to /var/log/syslog)

    ..Windowsexplorer.exe

    (from C:Users to C:Windowsexplorer.exe)

    Operating system independent path and directory names

    As seen in the table, absolute paths on Windows start with a drive letter and a colon; directories are separated by a backslash (»). On Linux and Mac, absolute paths start with a forward slash (‘/’), which also separates directories.

    You can access the separator of the currently used operating system with the constant File.separator or the method FileSystems.getDefault().getSeparator() and thus generate pathnames «manually» (i.e. by concatenating strings). For example like this:

    String homePath = System.getProperty("user.home"); String fileName = "test" + System.currentTimeMillis(); String filePath = homePath + File.separator + fileName; System.out.println("filePath = " + filePath);

    Code language: Java (java)

    Depending on the operating system we get a different output:

    • Windows: filePath = C:Userssvenwtest1578950760671
    • Linux: filePath = /home/sven/test1578950836130

    With the home directory, this works quite well, but with the temp directory (we get this from the system property «java.io.tmpdir») we get the following output:

    • Windows: filePath = C:UserssvenwAppDataLocalTemp\test1578950862590
    • Linux: filePath = /tmp/test1578950884314

    Did you spot the problem?

    On Windows, the path for the temporary directory already ends with a backslash. By adding a separator, our code creates a double backslash in the file path.

    We could now check if the directory name already ends with a separator and add it only if it is not present. But that is not necessary at all. You can construct file and directory names much more elegantly – completely without string operations, using the classes java.io.File and (from Java 7) java.nio.file.Path.

    «Old» Java File API vs. NIO.2 File API

    In Java 7, the «NIO.2 File API» was introduced with JSR 203 (NIO stands for «New I/O»). This provides a whole new set of classes for handling files (introduced in the previous article about writing and reading files).

    Files and directories were previously represented by the class java.io.File. This leads to confusion, especially for beginners, because the class name suggests that the class only represents files, not directories.

    In NIO.2, this task is taken over by the – now appropriately named – class java.nio.file.Path. Its interface has been completely rewritten compared to java.io.File.

    Constructing file and directory paths with java.io.File

    Let’s start with the «old» class, java.io.File. A file object can represent a filename, a directory name, a relative file or directory path, or an absolute file or directory path (where a file/directory name is actually also a relative file/directory path, relative to the directory in which the file/directory is located).

    java.io.file: File and directory names

    Representing file names with java.io.File

    You can define a filename (without specifying a directory) as follows (we stick to the pattern «test<timestamp>» used above):

    File file = new File("test" + System.currentTimeMillis());

    Code language: Java (java)

    You can now read the following information from the File object:

    Method Return value
    file.getName() test1578953190701
    file.getPath() test1578953190701
    file.getParent() / file.getParentFile() null
    file.getAbsolutePath() / file.getAbsoluteFile() /happycoders/git/filedemo/test1578953190701

    The method getName() returns the filename we passed to the constructor. getPath() returns the path, which in this case corresponds to the filename since we have not specified a directory. For the same reason, getParent() and getParentFile() both return null, the first method returns a String, the second a corresponding File object.

    Using the methods getAbsolutPath() and getAbsolutFile(), you map this file into the current working directory and get the complete path of the file including its directory and filename. These two methods also differ only in that the first returns a String, and the second returns a corresponding File object.

    There are also the methods getCanonicalPath() and getCanonicalFile(), which would return the same values as getAbsolutePath() and getAbsoluteFile() in this and the following examples. We will see in a later example, in which cases they can contain other values.

    Representing directory names with java.io.File

    The File object constructed in the previous section could just as well represent a directory with the same name instead of a file. The methods listed in the table above would return the same results.

    A distinction would only be possible if a file or directory with this name already exists. If a corresponding file exists, the method file.isFile() returns true. If, on the other hand, a directory with this name exists, the method file.isDirectory() returns true. If neither file nor directory exists, both methods return false. Depending on the further use, the File object can then be used either to create a directory or to create a file.

    java.io.File: Relative file and directory paths

    Relative file path with java.io.File

    To specify a directory, we can pass it to the File constructor as a parameter – in the simplest form as a String. With the following code, you put the test file into a tests directory:

    File file = new File("tests", "test" + System.currentTimeMillis());

    Code language: Java (java)

    The getters now provide the following information about the File object (with the differences to the previous example highlighted in bold):

    Method Return value
    file.getName() test1578953190701
    file.getPath() tests/test1578953190701
    file.getParent() / file.getParentFile() tests
    file.getAbsolutePath() / file.getAbsoluteFile() /happycoders/git/filedemo/tests/test1578953190701

    We can now see a difference between getName() and getPath(): the first method returns only the file name without the directory information, the second method returns the complete relative path. getParent() and getParentFile() (remember: the first method returns a String, the second a corresponding File object) now return the specified directory tests. In the absolute path information returned by getAbsolutePath() and getAbsoluteFile() (again: String vs. File), the subdirectory tests gets inserted accordingly.

    The directory can also be passed as a File object instead of a String:

    File directory = new File("tests"); File file = new File(directory, "test" + System.currentTimeMillis());

    Code language: Java (java)

    Relative file path with nested directories

    Several directory levels can also be nested:

    File testsDirectory = new File("tests"); File yearDirectory = new File(testsDirectory, "2020"); File dayDirectory = new File(yearDirectory, "2020-01-13"); File file = new File(dayDirectory, "test" + System.currentTimeMillis());

    Code language: Java (java)

    This allows us to construct directory paths of any depth without having to use the separator character even once. The example constructs a file object with the path tests/2020/2020-01-13/test1578953190701.

    What will the getParent() method return now? tests/2020/2020-01-13 or just 2020-01-13? Let’s try it…

    Method Return value
    file.getName() test1578953190701
    file.getPath() tests/2020/2020-01-13/test1578953190701
    file.getParent() / file.getParentFile() tests/2020/2020-01-13
    file.getAbsolutePath() / file.getAbsoluteFile() /happycoders/git/filedemo/tests/2020/2020-01-13/test1578953190701

    The parent, therefore, represents the path to the parent directory, not just its name. To access the name of the parent directory we can use file.getParentFile().getName().

    Relative directory path with java.io.File

    Also, in the examples from the previous section, test1578953190701 could be a directory instead of a file. The path does not allow any conclusions to be drawn.

    java.io.File: Absolute file and directory paths

    Absolute directory path with java.io.File

    Attention: We look at absolute paths in reverse order: We first construct the directory path and then the file path, since we cannot generate an absolute file path without an absolute directory path as a parent.

    (There is one exception, which we have already seen in the previous examples: We can obtain the absolute file path for a file in the current directory by invoking the File constructor with only the file name and then calling the method getAbsoluteFile() / getAbsolutePath() on the created File object.)

    We have the following options for constructing an absolute directory path:

    • from an absolute directory path represented as a String (therefore dependent on the operating system)
    • from the system properties mentioned at the beginning, like «user.home» and «java.io.tmpdir»
    • from the current directory

    Constructing an absolute directory path from a String

    Once we have the absolute directory path in a String (for example, from a configuration file), we can pass it directly to the File constructor. The following example uses a String constant for simplicity:

    File directory = new File("/var/log/myapp");

    Code language: Java (java)

    For this absolute directory, the File object’s getters return the following values:

    Method Return value
    file.getName() myapp
    file.getPath() /var/log/myapp
    file.getParent() / file.getParentFile() /var/log
    file.getAbsolutePath() / file.getAbsoluteFile() /var/log/myapp

    The Methods getPath(), getAbsolutePath() and getAbsoluteFile() now all return the absolute path of the directory. getParent() and getParentFile() return the absolute path of the parent directory.

    Constructing an absolute directory path from system properties

    Through the system properties user.home and java.io.tmpdir, you get – independent of the operating system – the user’s home directory and the temporary directory.

    The System.getProperty() method finally returns the path as a String, which we can then pass to the File constructor. Above, we saw that on Windows, the temporary directory has a trailing backslash, the home directory does not. Does that cause us problems at this point?

    We can use the following code to test it on Windows:

    String homeDir = System.getProperty("user.home"); System.out.println("homeDir = " + homeDir); System.out.println("homeDir as File object = " + new File(homeDir)); String tempDir = System.getProperty("java.io.tmpdir"); System.out.println("tempDir = " + tempDir); System.out.println("tempDir as File object = " + new File(tempDir));

    Code language: Java (java)

    The program delivers the following output:

    homeDir = C:Userssvenw homeDir as File object = C:Userssvenw tempDir = C:UserssvenwAppDataLocalTemp tempDir as File object = C:UserssvenwAppDataLocalTemp

    Code language: plaintext (plaintext)

    The unnecessary trailing backslash has been removed, so we don’t have to worry about anything.

    Creating an absolute directory path from the current directory

    Using what we know so far, we could construct the absolute directory path of the current directory as follows:

    File file = new File("dummy"); File absoluteFile = file.getAbsoluteFile(); File absoluteDirectory = absoluteFile.getParentFile();

    Code language: Java (java)

    Here we have generated a dummy file path, constructed the absolute path for it (which maps the file into the current directory), and then extracted the parent – the absolute path of the directory in which the file is located.

    Admittedly, this is rather cumbersome. Fortunately, there is a more elegant way: The current directory can also be read from a system property, user.dir, and then passed to the File constructor:

    File currentDir = new File(System.getProperty("user.dir"));

    Code language: Java (java)

    Absolute file path with java.io.File

    After having looked at different ways of creating an absolute directory path, we can now construct an absolute file path. All we have to do is pass the directory and filename to the File constructor.

    File tempDir = new File(System.getProperty("java.io.tmpdir")); File subDir = new File(tempDir, "myapp"); String fileName = "foo"; File file = new File(subDir, fileName);

    Code language: Java (java)

    For this example, the getters of the File object return the following values:

    Method Return value
    file.getName() foo
    file.getPath() /tmp/myapp/foo
    file.getParent() / file.getParentFile() /tmp/myapp
    file.getAbsolutePath() / file.getAbsoluteFile() /tmp/myapp/foo

    We see a similar pattern as in the example with the absolute directory path /var/log/myapp: The methods getPath(), getAbsolutePath() and getAbsoluteFile() return the absolute path of the file. And getParent() and getParentFile() return the absolute path of the parent directory.

    Attention:

    If you create a file object for a file in the current directory, it makes a difference whether you create the object with the current directory and filename or just the filename. The methods getAbsoluteFile() / getAbsolutePath() return the absolute file path in both cases. However, getPath() returns the absolute path only in the first case; whereas in the second case it returns only the filename. And getParent() and getParentFile() only return the parent directory in the first case, but null in the second case.

    java.io.file: Overview of File’s getter methods

    The following table summarizes what File‘s getters return depending on the file system object represented:

    Method File/directory name Relative file/directory path Absolute file/directory path
    getName() File/directory name File/directory name File/directory name
    getPath() File/directory name Relative file/directory path Absolute file/directory path
    getParent() / getParentFile() null Relative path to parent directory Absolute path to parent directory
    getAbsolutePath() / getAbsoluteFile() Absolute path from combination of current directory and file/directory name Absolute path from combination of current directory and relative file/directory path Absolute file/directory path

    Once again as a reminder: getParent() and getAbsolutePath() return a String; getParentFile() and getAbsoluteFile() return a corresponding File object.

    java.io.file: What is the difference between getCanonicalPath() / getCanonicalFile() and getAbsolutePath() / getAbsolutePath()?

    In all previous examples, the methods getCanonicalPath() and getCanonicalFile() would have returned the same result as getAbsolutePath() and getAbsoluteFile() – namely the respective absolute path (as String or File object).

    So what is the difference?

    A «canonical path» is unique; i.e., there is only one such path to a file. In contrast, there can be more than one absolute path to the same file. An example:

    For the file /var/log/syslog, this String is also the «canonical path». The same String is also an absolute path. However, there are other absolute paths, such as

    • /var/log/./syslog,
    • /var/log/../log/syslog,
    • /home/user/../../var/log/syslog,
    • as well as all paths that eventually point to /var/log/syslog via symbolic links.

    Constructing file and directory paths with java.nio.file.Path and Paths

    Although the interface of java.nio.file.Path has been completely changed from java.io.File, the underlying concepts have remained unchanged. Filenames, directory names, relative file and directory paths, and absolute file and directory paths are still the file system objects being represented.

    What was changed? In the following sections, you see how to construct Path objects, using the same structure and the same examples as with the File objects before.

    In the following sections, I will not make a distinction between file and directory names. We have already seen above that, as long as the corresponding file system object does not exist, its path does not indicate whether it is a file or a directory.

    java.nio.file.Path: File and directory names

    Instead of a constructor, we use a factory method for java.nio.file.Path to create instances. The factory method was originally located in the class java.nio.file.Paths (with «s» at the end), but in Java 11, it was also directly included in the Path class. We create a Path object for the file name «test<timestamp>» as follows:

    Path path = Paths.get("test" + System.currentTimeMillis());

    Code language: Java (java)

    Starting with Java 11, you can use Path.of() instead of Paths.get(). There is practically no difference. Internally, Paths.get() calls the newer method Path.of() and this in turn calls FileSystems.getDefault().getPath().

    Path path = Path.of("test" + System.currentTimeMillis());

    Code language: Java (java)

    The following methods provide information analogous to methods of the File class shown above:

    Method Return value
    path.getFileName() test1579037366379
    path.getNameCount() 1
    path.getName(0) test1579037366379
    path.getParent() null
    path.getRoot() null
    path.toAbsolutePath() /happycoders/git/filedemo/test1579037366379
    path.normalize() test1579037366379

    First of all: All methods shown – except for getNameCount() – return a Path object. There are no variants of these methods that return a String. The only way to convert a Path object into a String is to call its toString() method.

    The getFileName() method returns the name of the file or directory. getNameCount() is always 1 for a filename without directory information, or for directories without a parent directory. And the first name, retrievable by getName(0), is also the file/directory name. getParent() returns – like File‘s method with the same name – null. The method getRoot() also returns null, since a single filename is always relative. With toAbsolutePath() we map – analogous to File.getAbsolutePath() – the file/directory into the current directory and get the corresponding absolute path.

    Path.normalize() is similar to File.getCanonicalPath() with the difference that when normalizing a path, relative paths remain relative, while getCanonicalPath() always generates an absolute path for both absolute and relative File objects.

    java.nio.file.Path: Relative file and directory paths

    To include directories, Path offers two different approaches:

    • You can list all directories in the factory method Paths.get() or Path.of().
    • You can use its resolve() method to convert an existing Path object into a new Path object, where the resolve() method is equivalent to changing the directory with the Windows or Linux cd command.

    Constructing relative file and directory paths with Paths.get() / Path.of()

    You can pass any number of directory names to the factory methods. For example, you would construct the relative path tests/test1578953190701 as follows (the timestamp is hard-coded for simplicity):

    Path path = Paths.get("tests", "test1578953190701");

    Code language: Java (java)

    This Path object’s getters return the following results (I highlighted the differences to the individual file names in bold again):

    Method Return value
    path.getFileName() test1578953190701
    path.getNameCount() 2
    path.getName(0) tests
    path.getName(1) test1578953190701
    path.getParent() tests
    path.getRoot() null
    path.toAbsolutePath() /happycoders/git/filedemo/tests/test1578953190701
    path.normalize() tests/test1578953190701

    Due to the directory, nameCount has increased from 1 to 2. In the name array, the directory name was inserted at position 0; the file name has moved to position 1. getParent() also returns the directory name. The absolute path and the normalized version also contain the directory name.

    Constructing nested file and directory paths with Paths.get() / Path.of()

    If the file is to be located in the directory tests/2020/2020-01-13, call the factory method as follows:

    Path path = Paths.get("tests", "2020", "2020-01-13", "test1578953190701");

    Code language: Java (java)

    Here once again, the getters’ results:

    Method Return value
    path.getFileName() test1578953190701
    path.getNameCount() 4
    path.getName(0) tests
    path.getName(1) 2020
    path.getName(2) 2020-01-13
    path.getName(3) test1578953190701
    path.getParent() tests/2020/2020-01-13
    path.getRoot() null
    path.toAbsolutePath() /happycoders/git/filedemo/tests/2020/2020-01-13/test1578953190701
    path.normalize() tests/2020/2020-01-13/test1578953190701

    nameCount has been increased accordingly, and the name array contains all directories of the path as well as the filename. Again, getParent() returns the complete known path to the directory, not just its name.

    Constructing relative file and directory paths with Path.resolve()

    An alternative way to construct the Path object for the path tests/2020/2020-01-13/test1578953190701 is to use the resolve() method. It combines the path on which the method is called with the path passed to it:

    Path testsDir = Paths.get("tests"); Path yearDir = testsDir.resolve("2020"); Path dayDir = yearDir.resolve("2020-01-13"); Path path = dayDir.resolve("test1578953190701");

    Code language: GLSL (glsl)

    The resolve() operation is associative, i.e., the individual parts can also be joined in a different order, for example like this:

    Path testsDir = Paths.get("tests"); // tests Path yearDir = testsDir.resolve("2020"); // tests/2020 Path dayDir = Paths.get("2020-01-13"); // 2020-01-13 // 2020-01-13/test1578953190701 Path fileInDayDir = dayDir.resolve("test1578953190701"); // tests/2020/2020-01-13/test1578953190701 Path path = yearDir.resolve(fileInDayDir);

    Code language: Java (java)

    Shortcut: Path.resolveSibling()

    Let’s assume we have the Path object we constructed in the previous section, and we want to create another file in the same directory. If we still have access to the Path object representing the directory, we can call resolve() on it with the new filename. Otherwise, we could access the directory with getParent() and then call resolve():

    Path sibling = path.getParent().resolve("test" + System.currentTimeMillis());

    Code language: Java (java)

    Exactly for this purpose, there is the shortcut resolveSibling(), which saves you five keystrokes and bytes:

    Path sibling = path.resolveSibling("test" + System.currentTimeMillis());

    Code language: Java (java)

    java.nio.file.Path: Absolute file and directory paths

    Similar to java.io.File, we can also create an absolute path with java.nio.file.Path from a String that we read from a configuration file or a system property. We can pass this path, as it is, to the factory method. We do not need to split it up first. Using the directory /var/log/myapp as an example again:

    Path path = Paths.get("/var/log/myapp");

    Code language: Java (java)

    Of course, we can also modify an absolute path using the resolve() method. The following example corresponds to the example of the absolute file path with java.io.File:

    Path tempDir = Path.of(System.getProperty("java.io.tmpdir")); Path subDir = tempDir.resolve("myapp"); String fileName = "foo"; Path file = subDir.resolve(fileName);

    Code language: Java (java)

    For this absolute path, the getter methods return:

    Method Return value
    path.getFileName() foo
    path.getNameCount() 3
    path.getName(0) tmp
    path.getName(1) myapp
    path.getName(2) foo
    path.getParent() /tmp/myapp
    path.getRoot() /
    path.toAbsolutePath() /tmp/myapp/foo
    path.normalize() /tmp/myapp/foo

    Here we experience for the first time that path.getRoot() does not return null, but "/", the Linux root directory. On Windows, we would get «C:» here (unless the temporary directory is in a different file system). The root directory is not part of the name array.

    java.nio.file.Path: Overview of its getter methods

    Here you can see a summary of what Path‘s getters return:

    Method File/directory name Relative file/directory path Absolute file/directory path
    path.getFileName() File/directory name File/directory name File/directory name
    path.getNameCount() 1 Number of directories + file Number of directories + file
    path.getName(index) File/directory name File/directory names at the given position (0-based) File/directory names at the given position (0-based, root does not count)
    path.getParent() null Relative path to parent directory Absolute path to parent directory
    path.getRoot() null null The file system’s root, such as «/» or «C:»
    path.toAbsolutePath() Absolute path from combination of current directory and file/directory name Absolute path from combination of current directory and file/directory name Absolute file/directory path
    path.normalize() Normalized file/directory name Normalized relative file/directory name Normalized absolute file/directory name

    Summary and outlook

    This article gave a detailed overview of how to construct file and directory paths independent of the operating system using the classes File, Path, and Paths.

    My recommendation is to use only the NIO.2 classes Path and Paths from Java 7 on, and from Java 11 on, use only Path. If you need a File object for a particular file operation, you can always create one with Path.toFile().

    The following parts of the series will deal with the following topics:

    • Directory operations, such as reading the file list of a directory
    • Copying, moving, and deleting files
    • Creating temporary files
    • Read and write structured data with DataOutputStream and DataInputStream

    In the later course we come to advanced topics:

    • NIO channels and buffers introduced in Java 1.4, to speed up working with large files
    • Memory-mapped I/O for blazing-fast file access without streams
    • File locking, to access the same files in parallel – i.e., from several threads or processes – without conflicts

    Do you have any questions, suggestions, ideas for improvement? Then I would be pleased with a comment. Do you know others who find the topic interesting? Then I would be happy if you share the article by using one of the buttons below. Would you like to be informed when the next part appears? Then click here to sign up for the HappyCoders newsletter.

    Понравилась статья? Поделить с друзьями:
  • Java web start скачать windows 7 32 bit
  • Java virtual machine скачать для windows 10 64 bit
  • Java virtual machine launcher скачать для windows 10
  • Java virtual machine launcher ошибка как исправить на windows 10 minecraft
  • Java tm platform se binary скачать для windows 10