How can I change the current working directory from within a Java program? Everything I’ve been able to find about the issue claims that you simply can’t do it, but I can’t believe that that’s really the case.
I have a piece of code that opens a file using a hard-coded relative file path from the directory it’s normally started in, and I just want to be able to use that code from within a different Java program without having to start it from within a particular directory. It seems like you should just be able to call System.setProperty( "user.dir", "/path/to/dir" ), but as far as I can figure out, calling that line just silently fails and does nothing.
I would understand if Java didn’t allow you to do this, if it weren’t for the fact that it allows you to get the current working directory, and even allows you to open files using relative file paths….
asked May 8, 2009 at 14:54
2
There is no reliable way to do this in pure Java. Setting the user.dir property via System.setProperty() or java -Duser.dir=... does seem to affect subsequent creations of Files, but not e.g. FileOutputStreams.
The File(String parent, String child) constructor can help if you build up your directory path separately from your file path, allowing easier swapping.
An alternative is to set up a script to run Java from a different directory, or use JNI native code as suggested below.
The relevant OpenJDK bug was closed in 2008 as «will not fix».
Edric
23.5k13 gold badges79 silver badges89 bronze badges
answered May 8, 2009 at 14:59
Michael Myers♦Michael Myers
187k45 gold badges291 silver badges292 bronze badges
9
If you run your legacy program with ProcessBuilder, you will be able to specify its working directory.
answered May 8, 2009 at 15:04
PhiLhoPhiLho
40.1k6 gold badges95 silver badges132 bronze badges
1
There is a way to do this using the system property «user.dir». The key part to understand is that getAbsoluteFile() must be called (as shown below) or else relative paths will be resolved against the default «user.dir» value.
import java.io.*;
public class FileUtils
{
public static boolean setCurrentDirectory(String directory_name)
{
boolean result = false; // Boolean indicating whether directory was set
File directory; // Desired current working directory
directory = new File(directory_name).getAbsoluteFile();
if (directory.exists() || directory.mkdirs())
{
result = (System.setProperty("user.dir", directory.getAbsolutePath()) != null);
}
return result;
}
public static PrintWriter openOutputFile(String file_name)
{
PrintWriter output = null; // File to open for writing
try
{
output = new PrintWriter(new File(file_name).getAbsoluteFile());
}
catch (Exception exception) {}
return output;
}
public static void main(String[] args) throws Exception
{
FileUtils.openOutputFile("DefaultDirectoryFile.txt");
FileUtils.setCurrentDirectory("NewCurrentDirectory");
FileUtils.openOutputFile("CurrentDirectoryFile.txt");
}
}
answered Dec 20, 2012 at 23:00
Steve KSteve K
6456 silver badges8 bronze badges
1
It is possible to change the PWD, using JNA/JNI to make calls to libc. The JRuby guys have a handy java library for making POSIX calls called jnr-posix. Here’s the maven info
Flow
23.4k15 gold badges98 silver badges155 bronze badges
answered Nov 20, 2011 at 20:45
Allen RohnerAllen Rohner
1,1081 gold badge10 silver badges16 bronze badges
4
As mentioned you can’t change the CWD of the JVM but if you were to launch another process using Runtime.exec() you can use the overloaded method that lets you specify the working directory. This is not really for running your Java program in another directory but for many cases when one needs to launch another program like a Perl script for example, you can specify the working directory of that script while leaving the working dir of the JVM unchanged.
See Runtime.exec javadocs
Specifically,
public Process exec(String[] cmdarray,String[] envp, File dir) throws IOException
where dir is the working directory to run the subprocess in
answered Feb 6, 2013 at 15:20
BizmarckBizmarck
2,6432 gold badges33 silver badges47 bronze badges
1
If I understand correctly, a Java program starts with a copy of the current environment variables. Any changes via System.setProperty(String, String) are modifying the copy, not the original environment variables. Not that this provides a thorough reason as to why Sun chose this behavior, but perhaps it sheds a little light…
answered May 8, 2009 at 14:58
Adam PaynterAdam Paynter
46k33 gold badges147 silver badges164 bronze badges
2
The working directory is a operating system feature (set when the process starts).
Why don’t you just pass your own System property (-Dsomeprop=/my/path) and use that in your code as the parent of your File:
File f = new File ( System.getProperty("someprop"), myFilename)
answered May 8, 2009 at 14:59
raphaëλraphaëλ
6,3132 gold badges29 silver badges35 bronze badges
1
The smarter/easier thing to do here is to just change your code so that instead of opening the file assuming that it exists in the current working directory (I assume you are doing something like new File("blah.txt"), just build the path to the file yourself.
Let the user pass in the base directory, read it from a config file, fall back to user.dir if the other properties can’t be found, etc. But it’s a whole lot easier to improve the logic in your program than it is to change how environment variables work.
answered May 8, 2009 at 15:03
matt bmatt b
137k65 gold badges281 silver badges343 bronze badges
I have tried to invoke
String oldDir = System.setProperty("user.dir", currdir.getAbsolutePath());
It seems to work. But
File myFile = new File("localpath.ext");
InputStream openit = new FileInputStream(myFile);
throws a FileNotFoundException though
myFile.getAbsolutePath()
shows the correct path.
I have read this. I think the problem is:
- Java knows the current directory with the new setting.
- But the file handling is done by the operation system. It does not know the new set current directory, unfortunately.
The solution may be:
File myFile = new File(System.getPropety("user.dir"), "localpath.ext");
It creates a file Object as absolute one with the current directory which is known by the JVM. But that code should be existing in a used class, it needs changing of reused codes.
~~~~JcHartmut
answered May 28, 2014 at 20:09
1
You can use
new File(«relative/path»).getAbsoluteFile()
after
System.setProperty(«user.dir», «/some/directory»)
System.setProperty("user.dir", "C:/OtherProject");
File file = new File("data/data.csv").getAbsoluteFile();
System.out.println(file.getPath());
Will print
C:OtherProjectdatadata.csv
answered Jun 10, 2017 at 7:37
1
You can change the process’s actual working directory using JNI or JNA.
With JNI, you can use native functions to set the directory. The POSIX method is chdir(). On Windows, you can use SetCurrentDirectory().
With JNA, you can wrap the native functions in Java binders.
For Windows:
private static interface MyKernel32 extends Library {
public MyKernel32 INSTANCE = (MyKernel32) Native.loadLibrary("Kernel32", MyKernel32.class);
/** BOOL SetCurrentDirectory( LPCTSTR lpPathName ); */
int SetCurrentDirectoryW(char[] pathName);
}
For POSIX systems:
private interface MyCLibrary extends Library {
MyCLibrary INSTANCE = (MyCLibrary) Native.loadLibrary("c", MyCLibrary.class);
/** int chdir(const char *path); */
int chdir( String path );
}
answered Dec 18, 2019 at 17:51
Andy ThomasAndy Thomas
83.9k11 gold badges103 silver badges148 bronze badges
The other possible answer to this question may depend on the reason you are opening the file. Is this a property file or a file that has some configuration related to your application?
If this is the case you may consider trying to load the file through the classpath loader, this way you can load any file Java has access to.
answered May 8, 2009 at 15:04
Nathan FegerNathan Feger
18.9k11 gold badges61 silver badges70 bronze badges
If you run your commands in a shell you can write something like «java -cp» and add any directories you want separated by «:» if java doesnt find something in one directory it will go try and find them in the other directories, that is what I do.
answered Jul 31, 2012 at 15:48
lesolorzanovlesolorzanov
3,4857 gold badges34 silver badges53 bronze badges
Use FileSystemView
private FileSystemView fileSystemView;
fileSystemView = FileSystemView.getFileSystemView();
currentDirectory = new File(".");
//listing currentDirectory
File[] filesAndDirs = fileSystemView.getFiles(currentDirectory, false);
fileList = new ArrayList<File>();
dirList = new ArrayList<File>();
for (File file : filesAndDirs) {
if (file.isDirectory())
dirList.add(file);
else
fileList.add(file);
}
Collections.sort(dirList);
if (!fileSystemView.isFileSystemRoot(currentDirectory))
dirList.add(0, new File(".."));
Collections.sort(fileList);
//change
currentDirectory = fileSystemView.getParentDirectory(currentDirectory);
answered Sep 11, 2013 at 14:23
BorneqBorneq
2611 gold badge6 silver badges13 bronze badges
2
How can I change the current working directory from within a Java program? Everything I’ve been able to find about the issue claims that you simply can’t do it, but I can’t believe that that’s really the case.
I have a piece of code that opens a file using a hard-coded relative file path from the directory it’s normally started in, and I just want to be able to use that code from within a different Java program without having to start it from within a particular directory. It seems like you should just be able to call System.setProperty( "user.dir", "/path/to/dir" ), but as far as I can figure out, calling that line just silently fails and does nothing.
I would understand if Java didn’t allow you to do this, if it weren’t for the fact that it allows you to get the current working directory, and even allows you to open files using relative file paths….
asked May 8, 2009 at 14:54
2
There is no reliable way to do this in pure Java. Setting the user.dir property via System.setProperty() or java -Duser.dir=... does seem to affect subsequent creations of Files, but not e.g. FileOutputStreams.
The File(String parent, String child) constructor can help if you build up your directory path separately from your file path, allowing easier swapping.
An alternative is to set up a script to run Java from a different directory, or use JNI native code as suggested below.
The relevant OpenJDK bug was closed in 2008 as «will not fix».
Edric
23.5k13 gold badges79 silver badges89 bronze badges
answered May 8, 2009 at 14:59
Michael Myers♦Michael Myers
187k45 gold badges291 silver badges292 bronze badges
9
If you run your legacy program with ProcessBuilder, you will be able to specify its working directory.
answered May 8, 2009 at 15:04
PhiLhoPhiLho
40.1k6 gold badges95 silver badges132 bronze badges
1
There is a way to do this using the system property «user.dir». The key part to understand is that getAbsoluteFile() must be called (as shown below) or else relative paths will be resolved against the default «user.dir» value.
import java.io.*;
public class FileUtils
{
public static boolean setCurrentDirectory(String directory_name)
{
boolean result = false; // Boolean indicating whether directory was set
File directory; // Desired current working directory
directory = new File(directory_name).getAbsoluteFile();
if (directory.exists() || directory.mkdirs())
{
result = (System.setProperty("user.dir", directory.getAbsolutePath()) != null);
}
return result;
}
public static PrintWriter openOutputFile(String file_name)
{
PrintWriter output = null; // File to open for writing
try
{
output = new PrintWriter(new File(file_name).getAbsoluteFile());
}
catch (Exception exception) {}
return output;
}
public static void main(String[] args) throws Exception
{
FileUtils.openOutputFile("DefaultDirectoryFile.txt");
FileUtils.setCurrentDirectory("NewCurrentDirectory");
FileUtils.openOutputFile("CurrentDirectoryFile.txt");
}
}
answered Dec 20, 2012 at 23:00
Steve KSteve K
6456 silver badges8 bronze badges
1
It is possible to change the PWD, using JNA/JNI to make calls to libc. The JRuby guys have a handy java library for making POSIX calls called jnr-posix. Here’s the maven info
Flow
23.4k15 gold badges98 silver badges155 bronze badges
answered Nov 20, 2011 at 20:45
Allen RohnerAllen Rohner
1,1081 gold badge10 silver badges16 bronze badges
4
As mentioned you can’t change the CWD of the JVM but if you were to launch another process using Runtime.exec() you can use the overloaded method that lets you specify the working directory. This is not really for running your Java program in another directory but for many cases when one needs to launch another program like a Perl script for example, you can specify the working directory of that script while leaving the working dir of the JVM unchanged.
See Runtime.exec javadocs
Specifically,
public Process exec(String[] cmdarray,String[] envp, File dir) throws IOException
where dir is the working directory to run the subprocess in
answered Feb 6, 2013 at 15:20
BizmarckBizmarck
2,6432 gold badges33 silver badges47 bronze badges
1
If I understand correctly, a Java program starts with a copy of the current environment variables. Any changes via System.setProperty(String, String) are modifying the copy, not the original environment variables. Not that this provides a thorough reason as to why Sun chose this behavior, but perhaps it sheds a little light…
answered May 8, 2009 at 14:58
Adam PaynterAdam Paynter
46k33 gold badges147 silver badges164 bronze badges
2
The working directory is a operating system feature (set when the process starts).
Why don’t you just pass your own System property (-Dsomeprop=/my/path) and use that in your code as the parent of your File:
File f = new File ( System.getProperty("someprop"), myFilename)
answered May 8, 2009 at 14:59
raphaëλraphaëλ
6,3132 gold badges29 silver badges35 bronze badges
1
The smarter/easier thing to do here is to just change your code so that instead of opening the file assuming that it exists in the current working directory (I assume you are doing something like new File("blah.txt"), just build the path to the file yourself.
Let the user pass in the base directory, read it from a config file, fall back to user.dir if the other properties can’t be found, etc. But it’s a whole lot easier to improve the logic in your program than it is to change how environment variables work.
answered May 8, 2009 at 15:03
matt bmatt b
137k65 gold badges281 silver badges343 bronze badges
I have tried to invoke
String oldDir = System.setProperty("user.dir", currdir.getAbsolutePath());
It seems to work. But
File myFile = new File("localpath.ext");
InputStream openit = new FileInputStream(myFile);
throws a FileNotFoundException though
myFile.getAbsolutePath()
shows the correct path.
I have read this. I think the problem is:
- Java knows the current directory with the new setting.
- But the file handling is done by the operation system. It does not know the new set current directory, unfortunately.
The solution may be:
File myFile = new File(System.getPropety("user.dir"), "localpath.ext");
It creates a file Object as absolute one with the current directory which is known by the JVM. But that code should be existing in a used class, it needs changing of reused codes.
~~~~JcHartmut
answered May 28, 2014 at 20:09
1
You can use
new File(«relative/path»).getAbsoluteFile()
after
System.setProperty(«user.dir», «/some/directory»)
System.setProperty("user.dir", "C:/OtherProject");
File file = new File("data/data.csv").getAbsoluteFile();
System.out.println(file.getPath());
Will print
C:OtherProjectdatadata.csv
answered Jun 10, 2017 at 7:37
1
You can change the process’s actual working directory using JNI or JNA.
With JNI, you can use native functions to set the directory. The POSIX method is chdir(). On Windows, you can use SetCurrentDirectory().
With JNA, you can wrap the native functions in Java binders.
For Windows:
private static interface MyKernel32 extends Library {
public MyKernel32 INSTANCE = (MyKernel32) Native.loadLibrary("Kernel32", MyKernel32.class);
/** BOOL SetCurrentDirectory( LPCTSTR lpPathName ); */
int SetCurrentDirectoryW(char[] pathName);
}
For POSIX systems:
private interface MyCLibrary extends Library {
MyCLibrary INSTANCE = (MyCLibrary) Native.loadLibrary("c", MyCLibrary.class);
/** int chdir(const char *path); */
int chdir( String path );
}
answered Dec 18, 2019 at 17:51
Andy ThomasAndy Thomas
83.9k11 gold badges103 silver badges148 bronze badges
The other possible answer to this question may depend on the reason you are opening the file. Is this a property file or a file that has some configuration related to your application?
If this is the case you may consider trying to load the file through the classpath loader, this way you can load any file Java has access to.
answered May 8, 2009 at 15:04
Nathan FegerNathan Feger
18.9k11 gold badges61 silver badges70 bronze badges
If you run your commands in a shell you can write something like «java -cp» and add any directories you want separated by «:» if java doesnt find something in one directory it will go try and find them in the other directories, that is what I do.
answered Jul 31, 2012 at 15:48
lesolorzanovlesolorzanov
3,4857 gold badges34 silver badges53 bronze badges
Use FileSystemView
private FileSystemView fileSystemView;
fileSystemView = FileSystemView.getFileSystemView();
currentDirectory = new File(".");
//listing currentDirectory
File[] filesAndDirs = fileSystemView.getFiles(currentDirectory, false);
fileList = new ArrayList<File>();
dirList = new ArrayList<File>();
for (File file : filesAndDirs) {
if (file.isDirectory())
dirList.add(file);
else
fileList.add(file);
}
Collections.sort(dirList);
if (!fileSystemView.isFileSystemRoot(currentDirectory))
dirList.add(0, new File(".."));
Collections.sort(fileList);
//change
currentDirectory = fileSystemView.getParentDirectory(currentDirectory);
answered Sep 11, 2013 at 14:23
BorneqBorneq
2611 gold badge6 silver badges13 bronze badges
2
How can I change the current working directory from within a Java program? Everything I’ve been able to find about the issue claims that you simply can’t do it, but I can’t believe that that’s really the case.
I have a piece of code that opens a file using a hard-coded relative file path from the directory it’s normally started in, and I just want to be able to use that code from within a different Java program without having to start it from within a particular directory. It seems like you should just be able to call System.setProperty( "user.dir", "/path/to/dir" ), but as far as I can figure out, calling that line just silently fails and does nothing.
I would understand if Java didn’t allow you to do this, if it weren’t for the fact that it allows you to get the current working directory, and even allows you to open files using relative file paths….
asked May 8, 2009 at 14:54
2
There is no reliable way to do this in pure Java. Setting the user.dir property via System.setProperty() or java -Duser.dir=... does seem to affect subsequent creations of Files, but not e.g. FileOutputStreams.
The File(String parent, String child) constructor can help if you build up your directory path separately from your file path, allowing easier swapping.
An alternative is to set up a script to run Java from a different directory, or use JNI native code as suggested below.
The relevant OpenJDK bug was closed in 2008 as «will not fix».
Edric
23.5k13 gold badges79 silver badges89 bronze badges
answered May 8, 2009 at 14:59
Michael Myers♦Michael Myers
187k45 gold badges291 silver badges292 bronze badges
9
If you run your legacy program with ProcessBuilder, you will be able to specify its working directory.
answered May 8, 2009 at 15:04
PhiLhoPhiLho
40.1k6 gold badges95 silver badges132 bronze badges
1
There is a way to do this using the system property «user.dir». The key part to understand is that getAbsoluteFile() must be called (as shown below) or else relative paths will be resolved against the default «user.dir» value.
import java.io.*;
public class FileUtils
{
public static boolean setCurrentDirectory(String directory_name)
{
boolean result = false; // Boolean indicating whether directory was set
File directory; // Desired current working directory
directory = new File(directory_name).getAbsoluteFile();
if (directory.exists() || directory.mkdirs())
{
result = (System.setProperty("user.dir", directory.getAbsolutePath()) != null);
}
return result;
}
public static PrintWriter openOutputFile(String file_name)
{
PrintWriter output = null; // File to open for writing
try
{
output = new PrintWriter(new File(file_name).getAbsoluteFile());
}
catch (Exception exception) {}
return output;
}
public static void main(String[] args) throws Exception
{
FileUtils.openOutputFile("DefaultDirectoryFile.txt");
FileUtils.setCurrentDirectory("NewCurrentDirectory");
FileUtils.openOutputFile("CurrentDirectoryFile.txt");
}
}
answered Dec 20, 2012 at 23:00
Steve KSteve K
6456 silver badges8 bronze badges
1
It is possible to change the PWD, using JNA/JNI to make calls to libc. The JRuby guys have a handy java library for making POSIX calls called jnr-posix. Here’s the maven info
Flow
23.4k15 gold badges98 silver badges155 bronze badges
answered Nov 20, 2011 at 20:45
Allen RohnerAllen Rohner
1,1081 gold badge10 silver badges16 bronze badges
4
As mentioned you can’t change the CWD of the JVM but if you were to launch another process using Runtime.exec() you can use the overloaded method that lets you specify the working directory. This is not really for running your Java program in another directory but for many cases when one needs to launch another program like a Perl script for example, you can specify the working directory of that script while leaving the working dir of the JVM unchanged.
See Runtime.exec javadocs
Specifically,
public Process exec(String[] cmdarray,String[] envp, File dir) throws IOException
where dir is the working directory to run the subprocess in
answered Feb 6, 2013 at 15:20
BizmarckBizmarck
2,6432 gold badges33 silver badges47 bronze badges
1
If I understand correctly, a Java program starts with a copy of the current environment variables. Any changes via System.setProperty(String, String) are modifying the copy, not the original environment variables. Not that this provides a thorough reason as to why Sun chose this behavior, but perhaps it sheds a little light…
answered May 8, 2009 at 14:58
Adam PaynterAdam Paynter
46k33 gold badges147 silver badges164 bronze badges
2
The working directory is a operating system feature (set when the process starts).
Why don’t you just pass your own System property (-Dsomeprop=/my/path) and use that in your code as the parent of your File:
File f = new File ( System.getProperty("someprop"), myFilename)
answered May 8, 2009 at 14:59
raphaëλraphaëλ
6,3132 gold badges29 silver badges35 bronze badges
1
The smarter/easier thing to do here is to just change your code so that instead of opening the file assuming that it exists in the current working directory (I assume you are doing something like new File("blah.txt"), just build the path to the file yourself.
Let the user pass in the base directory, read it from a config file, fall back to user.dir if the other properties can’t be found, etc. But it’s a whole lot easier to improve the logic in your program than it is to change how environment variables work.
answered May 8, 2009 at 15:03
matt bmatt b
137k65 gold badges281 silver badges343 bronze badges
I have tried to invoke
String oldDir = System.setProperty("user.dir", currdir.getAbsolutePath());
It seems to work. But
File myFile = new File("localpath.ext");
InputStream openit = new FileInputStream(myFile);
throws a FileNotFoundException though
myFile.getAbsolutePath()
shows the correct path.
I have read this. I think the problem is:
- Java knows the current directory with the new setting.
- But the file handling is done by the operation system. It does not know the new set current directory, unfortunately.
The solution may be:
File myFile = new File(System.getPropety("user.dir"), "localpath.ext");
It creates a file Object as absolute one with the current directory which is known by the JVM. But that code should be existing in a used class, it needs changing of reused codes.
~~~~JcHartmut
answered May 28, 2014 at 20:09
1
You can use
new File(«relative/path»).getAbsoluteFile()
after
System.setProperty(«user.dir», «/some/directory»)
System.setProperty("user.dir", "C:/OtherProject");
File file = new File("data/data.csv").getAbsoluteFile();
System.out.println(file.getPath());
Will print
C:OtherProjectdatadata.csv
answered Jun 10, 2017 at 7:37
1
You can change the process’s actual working directory using JNI or JNA.
With JNI, you can use native functions to set the directory. The POSIX method is chdir(). On Windows, you can use SetCurrentDirectory().
With JNA, you can wrap the native functions in Java binders.
For Windows:
private static interface MyKernel32 extends Library {
public MyKernel32 INSTANCE = (MyKernel32) Native.loadLibrary("Kernel32", MyKernel32.class);
/** BOOL SetCurrentDirectory( LPCTSTR lpPathName ); */
int SetCurrentDirectoryW(char[] pathName);
}
For POSIX systems:
private interface MyCLibrary extends Library {
MyCLibrary INSTANCE = (MyCLibrary) Native.loadLibrary("c", MyCLibrary.class);
/** int chdir(const char *path); */
int chdir( String path );
}
answered Dec 18, 2019 at 17:51
Andy ThomasAndy Thomas
83.9k11 gold badges103 silver badges148 bronze badges
The other possible answer to this question may depend on the reason you are opening the file. Is this a property file or a file that has some configuration related to your application?
If this is the case you may consider trying to load the file through the classpath loader, this way you can load any file Java has access to.
answered May 8, 2009 at 15:04
Nathan FegerNathan Feger
18.9k11 gold badges61 silver badges70 bronze badges
If you run your commands in a shell you can write something like «java -cp» and add any directories you want separated by «:» if java doesnt find something in one directory it will go try and find them in the other directories, that is what I do.
answered Jul 31, 2012 at 15:48
lesolorzanovlesolorzanov
3,4857 gold badges34 silver badges53 bronze badges
Use FileSystemView
private FileSystemView fileSystemView;
fileSystemView = FileSystemView.getFileSystemView();
currentDirectory = new File(".");
//listing currentDirectory
File[] filesAndDirs = fileSystemView.getFiles(currentDirectory, false);
fileList = new ArrayList<File>();
dirList = new ArrayList<File>();
for (File file : filesAndDirs) {
if (file.isDirectory())
dirList.add(file);
else
fileList.add(file);
}
Collections.sort(dirList);
if (!fileSystemView.isFileSystemRoot(currentDirectory))
dirList.add(0, new File(".."));
Collections.sort(fileList);
//change
currentDirectory = fileSystemView.getParentDirectory(currentDirectory);
answered Sep 11, 2013 at 14:23
BorneqBorneq
2611 gold badge6 silver badges13 bronze badges
2
В этом посте будет обсуждаться, как переместить каталог в Java с одного пути на другой.
Есть несколько способов переместить каталог в простой Java и с использованием сторонних библиотек. Они подробно обсуждаются ниже:
1. Использование NIO
Начиная с Java 1.7, JDK имеет java.nio.file.Files, который предлагает несколько статических методов для работы с файлами и каталогами. Мы можем использовать его move(Path source, Path target, CopyOption… options) способ перемещения каталога.
Этот метод принимает путь к перемещаемому каталогу, путь к целевому каталогу и необязательный параметр, указывающий, как выполняется перемещение. По умолчанию перемещение завершается ошибкой, если целевой каталог уже существует. REPLACE_EXISTING опция указана. Если источник и цель ссылаются на один и тот же каталог, метод завершается без перемещения каталога. Если исходный каталог не существует, java.nio.file.NoSuchFileException бросается.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.StandardCopyOption; class Main { public static void main(String[] args) { File from = new File(«/var/www/src»); File to = new File(«/var/www/dest»); try { Files.move(from.toPath(), to.toPath(), StandardCopyOption.REPLACE_EXISTING); System.out.println(«Directory moved successfully.»); } catch (IOException ex) { ex.printStackTrace(); } } } |
Скачать код
2. Использование Apache Commons IO
Apache Commons IO FileUtils класс имеет несколько служебных методов для работы с файлами. Мы можем использовать его moveDirectory(File srcDir, File destDir) способ перемещения каталога.
Если целевой каталог уже существует, этот метод выдает org.apache.commons.io.FileExistsException. Если исходный каталог не существует, java.io.FileNotFoundException бросается. Если при перемещении каталога возникает ошибка ввода-вывода, java.io.IOException бросается.
Основным преимуществом использования Apache Commons IO является то, что он работает, даже если место назначения находится в другой файловой системе.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; class Main { public static void main(String[] args) { File from = new File(«/var/www/src»); File to = new File(«/var/www/dest»); try { FileUtils.moveDirectory(from, to); System.out.println(«Directory moved successfully.»); } catch (IOException ex) { ex.printStackTrace(); } } } |
Скачать код
3. Использование renameTo() метод
Мы также можем использовать renameTo(File dest) метод File класс, который может перемещать каталог в той же файловой системе.
Этот метод зависит от платформы, не является атомарным и не работает, если место назначения существует заранее. Он даже не генерирует исключение при сбое. Поэтому мы всегда должны проверять возвращаемое значение этого метода, чтобы убедиться, что операция перемещения прошла успешно.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import java.io.File; import java.io.IOException; class Main { public static void main(String[] args) { File from = new File(«/var/www/src»); File to = new File(«/var/www/dest»); boolean success = from.renameTo(to); if (success) { System.out.println(«Directory Moved Successfully»); } else { System.out.println(«Directory Moved Failed»); } } } |
Скачать код
4. Пользовательская процедура перемещения
Наконец, мы можем написать собственную процедуру для перемещения каталога. Идея состоит в том, чтобы перебирать файлы в исходном каталоге и перемещать их по отдельности. Если каталог содержит какие-либо подкаталоги, выполните это рекурсивно. Вот рабочий код:
|
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 |
import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; class Main { private static boolean moveDir(Path src, Path dest) { if (src.toFile().isDirectory()) { for (File file: src.toFile().listFiles()) { moveDir(file.toPath(), dest.resolve(src.relativize(file.toPath()))); } } try { Files.move(src, dest, StandardCopyOption.REPLACE_EXISTING); return true; } catch (IOException e) { return false; } } public static void main(String[] args) { File from = new File(«/var/www/src»); File to = new File(«/var/www/dest»); boolean success = moveDir(from.toPath(), to.toPath()); if (success) { System.out.println(«File Moved Successfully»); } else { System.out.println(«File Moved Failed»); } } } |
Скачать код
Это все о перемещении каталога в Java.
Также см:
Переместить файл в Java
Спасибо за чтение.
Пожалуйста, используйте наш онлайн-компилятор размещать код в комментариях, используя C, C++, Java, Python, JavaScript, C#, PHP и многие другие популярные языки программирования.
Как мы? Порекомендуйте нас своим друзьям и помогите нам расти. Удачного кодирования 🙂
Ответ на:
комментарий
от urxvt 15.05.12 15:55:38 MSK
Ответ на:
комментарий
от TDrive 15.05.12 15:59:12 MSK
Нет, к сожалению не работает. Свойство меняется, а каталог нет. Вычитал, что в Java вообще нельзя менять директорию в которой исполняется программа, но чё то не верится что разработчики java на столько упоротые.
★★★★★
(15.05.12 16:46:02 MSK)
- Показать ответы
- Ссылка
Ответ на:
комментарий
от TDrive 15.05.12 16:46:02 MSK
зато прекрасно верится, что ты настолько упорот, что не можешь выполнить работу не привязываясь к текущему каталогу
yyk ★★★★★
(15.05.12 18:07:27 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от yyk 15.05.12 18:07:27 MSK
Например если писать демон, нужно что бы он после запуска переходил в /. Что бы не занимать папку из которой его запустили, на всякий случай.
Ты предлагаешь все демоны на java хранить в корне? И кто из нас упорот?
★★★★★
(15.05.12 18:30:27 MSK)
- Показать ответы
- Ссылка
Ответ на:
комментарий
от TDrive 15.05.12 18:30:27 MSK
А каким образом этот недостойный и негодный во всех отношениях «демон на java» будет занимать твою «папку»?
anonymous
(15.05.12 19:35:50 MSK)
- Показать ответы
- Ссылка
Ответ на:
комментарий
от anonymous 15.05.12 19:35:50 MSK
Очевидно же, что папок на всех демонов не хватит, недавно сам Дьявол выступал по телевизору, сказал, что придется потесниться. Я специально на своем ноутбуке посоздавал пустых новых папок, ибо процесс не сложный, теперь жру^W жду наплива демонов.
anonymous
(15.05.12 19:41:44 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от TDrive 15.05.12 16:46:02 MSK
Вычитал, что в Java вообще нельзя менять директорию в которой исполняется программа
это внешнее по отношению с джава-машине свойство и изнутри ты его не поменяешь. Разве что Runtime.getRuntime().exec()
★★★☆
(15.05.12 19:44:39 MSK)
- Ссылка
Ответ на:
комментарий
от TDrive 15.05.12 18:30:27 MSK
нужно что бы он после запуска переходил в /
что это за ахинея? что значит «переходил»?
★★★☆
(15.05.12 19:45:40 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от anonymous 15.05.12 19:35:50 MSK
Будет мешать отмонтированию файловой системы. Может быть ещё что то, не помню. По этому считается хорошим тоном менять рабочую директорию на корень.
★★★★★
(15.05.12 19:49:17 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от JFreeM 15.05.12 19:45:40 MSK
менял директорию в которой выполняется.
★★★★★
(15.05.12 19:51:34 MSK)
- Ссылка
Ответ на:
комментарий
от TDrive 15.05.12 19:49:17 MSK
Будет мешать отмонтированию файловой системы.
т.е. у вас java лежит на файловой системе которую могут отмонтировать? Интересное архитектурное решение…
По этому считается хорошим тоном менять рабочую директорию на корень.
где считается?
★★★☆
(15.05.12 19:51:51 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от anonymous 15.05.12 19:41:44 MSK
Вообще я очень удивлен, что в Java этого нету. Теперь даже и не знаю каких ещё сюрпризов ждать от этого «замечательного» ЯП.
★★★★★
(15.05.12 19:54:22 MSK)
- Ссылка
Will Not Fix
неужели это так сложно?
Если вас интересует почему так, почитайте обсуждения на последней ссылке. А разработчики джавы чуть больше понимают в программировании, я вас уверяю.
★★★☆
(15.05.12 19:57:03 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от JFreeM 15.05.12 19:51:51 MSK
т.е. у вас java лежит на файловой системе которую могут отмонтировать? Интересное архитектурное решение…
«могут отмонтировать» это не значит что её каждый день монтируют/отмонтируют. Мало ли что может понадобиться.
где считается?
Ну в книгах по программированию такое советовали. За всех конечно не скажу, но совет вполне обоснован.
★★★★★
(15.05.12 19:58:07 MSK)
- Ссылка
Твоя программа — это процесс. Изменение текущей директории процесса есть изменение переменной, которая отвечает за пути к файлам. Т.е. при попытке открыть ./1.txt ты откроешь файл в /, а не в каталоге, из которого запущен процесс. Если у тебя рабочие файлы процесса в директории, которую можно отмонтировать, то смена текущего каталога процесса никак от этого не спасет. Разве что ты будешь при этом все файлы копировать тоже в /.
- Показать ответ
- Ссылка
Ответ на:
комментарий
от JFreeM 15.05.12 19:57:03 MSK
А разработчики джавы чуть больше понимают в программировании
Больше чем разработчики других ЯП? Везде есть, а в java нету.
Первые 3 ссылки читал, 4 потом прочитаю, чё то там букв много.
★★★★★
(15.05.12 20:01:44 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от TDrive 15.05.12 20:01:44 MSK
чё то там букв много.
шли бы вы на питоне/рубях педалить, а потом люди думают, что разработчики на джаве идиоты…
★★★☆
(15.05.12 20:02:56 MSK)
- Показать ответы
- Ссылка
Ответ на:
комментарий
от vurdalak 15.05.12 20:01:28 MSK
Ответ на:
комментарий
от TDrive 15.05.12 20:03:39 MSK
Ответ на:
комментарий
от JFreeM 15.05.12 20:02:56 MSK
Лол. А чё мало что ли? У меня прокрутка в низ улетела, ещё и на английском. Я всё это 30 мин переводить буду. Так что ваши претензии высосаны из пальца.
★★★★★
(15.05.12 20:05:58 MSK)
- Ссылка
Ответ на:
комментарий
от JFreeM 15.05.12 20:02:56 MSK
А что плохого в змее-то?
jessey
(15.05.12 20:06:51 MSK)
- Ссылка
Ответ на:
комментарий
от vurdalak 15.05.12 20:05:49 MSK
Если ты просто откроешь директорию bash. Отмонтировать ты её не сможешь. При чём тут пути к файлам?
★★★★★
(15.05.12 20:08:09 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от TDrive 15.05.12 20:08:09 MSK
Если ты просто откроешь директорию bash.
Объясни уже по человечески, как это проверить. Как можно «открыть директорию» командным интерпретатором?
- Показать ответ
- Ссылка
Ответ на:
комментарий
от vurdalak 15.05.12 20:09:27 MSK
Консоль открой и cd в какую нибудь примонтированную директорию. А потом попробуй отмонтировать.
★★★★★
(15.05.12 20:11:42 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от TDrive 15.05.12 20:11:42 MSK
Хм. Видимо, баш для чего-то читает текущий каталог. Что не обязательно делает твой код на джаве.
- Показать ответ
- Ссылка
Ответ на:
комментарий
от vurdalak 15.05.12 20:17:59 MSK
Ответ на:
комментарий
от TDrive 15.05.12 20:23:20 MSK
Ответ на:
комментарий
от vurdalak 15.05.12 20:25:07 MSK
Ответ на:
комментарий
от vurdalak 15.05.12 20:25:07 MSK
Ну да, получается только так.
★★★★★
(15.05.12 20:26:55 MSK)
- Ссылка
Ответ на:
комментарий
от TDrive 15.05.12 18:30:27 MSK
если писать демон, нужно что бы он после запуска переходил в /
Непременно целиком и полносью на джаве. Ведь обвязка на shell — моветон, и /etc/init.d пора удалять.
anonymous
(15.05.12 21:22:18 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от anonymous 15.05.12 21:22:18 MSK
Зачем удалять? Просто напишем systemj и скрипты на джаве, которые будут запускать демонов.
- Ссылка
А конкретное практическое применение-то какое? Я имею ввиду отмонтирование раздела, с которого запущена java-программа? Может стоит язык программирования выбирать под задачу, а не пытаться делать на нём то, для чего он плохо подходит?
Java-программа вообще должна мало что знать о системе, на которой она работает. Как ты представляешь себе смену рабочего каталога в аплете? А в сервлете?
Если за 15 (?) лет этой возможности так и не появилось, то может не стоит доказывать людям, что это проблема языка, а выбрать более подходящий инстурмент, либо наконец осознать, что это ненужно?
roy ★★★★★
(16.05.12 10:05:25 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от vurdalak 15.05.12 20:25:51 MSK
И да, кастую в тред тех, кто ответит, почему процесс привязывает к себе каталог.
jar — архив, который _сразу весь_ не распаковывается никуда, а только по мере надобности их него «достаётся» требуемое. Как во время работы погрузить требуемый класс, если ты отмонтировал каталог? По аналогии с офтопичными exe-шниками с ресурсами — когда понадобится ресурс (и вообще — понадобится ли в тесущей сессии) — хз.
yyk ★★★★★
(16.05.12 10:37:00 MSK)
- Показать ответы
- Ссылка
Ответ на:
комментарий
от yyk 16.05.12 10:37:00 MSK
это сколько минут надо изучать жабку, чтобы не знать этого? А срать кирпичами на форуме время есть…
yyk ★★★★★
(16.05.12 10:39:01 MSK)
- Ссылка
Ответ на:
комментарий
от roy 16.05.12 10:05:25 MSK
а не пытаться делать на нём то, для чего он плохо подходит?
Я только начал учить java, откуда я знаю для чего он подходит а для чего нет?
Как ты представляешь себе смену рабочего каталога в аплете? А в сервлете?
А как представить в аплете System.getRuntime().exec() или ProcessBuilder()?
Если за 15 (?) лет этой возможности так и не появилось, то может не стоит доказывать людям, что это проблема языка, а выбрать более подходящий инстурмент, либо наконец осознать, что это ненужно?
Я ничего не доказывая. Просто очень удивился тому, что в Java нет такой возможности. Это первый ЯП в котором я встретил такое.
А потом прилетели java-программисты и начали рассказывать что мне нужно, а что не нужно. И советовать «шли бы вы на питоне/рубях педалить».
Подозреваю, что у фанатов java какой то скрыты комплекс на эту тему.
★★★★★
(16.05.12 14:22:49 MSK)
- Показать ответы
- Ссылка
Ответ на:
комментарий
от yyk 16.05.12 10:37:00 MSK
Опять не в ту сторону.
★★★★★
(16.05.12 14:23:16 MSK)
- Ссылка
Ответ на:
комментарий
от TDrive 16.05.12 14:22:49 MSK
А как представить в аплете System.getRuntime().exec()
апще т по дефолту это запрещено и ты этого не сделаешь. Почитай про java security что ли)
Java’s security model is focused on protecting users from hostile programs downloaded from untrusted sources across a network. To accomplish this goal, Java provides a customizable «sandbox» in which Java programs run. A Java program must play only inside its sandbox. It can do anything within the boundaries of its sandbox, but it can’t take any action outside those boundaries. The sandbox for untrusted Java applets, for example, prohibits many activities, including:
*Reading or writing to the local disk
*Making a network connection to any host, except the host from which the applet came
*Creating a new process
*Loading a new dynamic library and directly calling a native method
★★★☆
(16.05.12 14:34:39 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от TDrive 16.05.12 14:22:49 MSK
Я ничего не доказывая. Просто очень удивился тому, что в Java нет такой возможности. Это первый ЯП в котором я встретил такое.
Т.е. вот это: «чё то не верится что разработчики java на столько упоротые» — это просто выражение удивления? А, ну тогда извини, что тебя «неупоротого» не так поняли…
А потом прилетели java-программисты и начали рассказывать что мне нужно, а что не нужно.
И этот с дислексией… Тебе попытались рассказать почему этого нет, и намекнули что это можно обойти.
yyk ★★★★★
(16.05.12 14:40:09 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от JFreeM 16.05.12 14:34:39 MSK
апще т по дефолту это запрещено и ты этого не сделаешь. Почитай про java security что ли)
Ну вот, я об этом и говорю.
★★★★★
(16.05.12 14:54:28 MSK)
- Ссылка
Ответ на:
комментарий
от yyk 16.05.12 14:40:09 MSK
Тебе попытались рассказать почему этого нет, и намекнули что это можно обойти.
Видимо это «шли бы вы на питоне/рубях педалить» был тонкий намёк, объясняющий как обходить нехватку функционала в java?
★★★★★
(16.05.12 15:01:10 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от TDrive 16.05.12 15:01:10 MSK
видимо только то, что у тебя точно дислексия. За сим — к доктору.
yyk ★★★★★
(16.05.12 15:26:57 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от yyk 16.05.12 15:26:57 MSK
Ответ на:
комментарий
от TDrive 16.05.12 15:44:47 MSK
Другого я и не ожидал.
Это было с самого начала понятно, что ты другого не ждёшь и другое тебе не нужно. Постановка задачи где? Иди в пень, боярин…
yyk ★★★★★
(16.05.12 16:11:41 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от TDrive 16.05.12 14:22:49 MSK
Я ничего не доказывая.
А потом прилетели java-программисты и начали рассказывать что мне нужно, а что не нужно.
По-моему, упоротыми java-разработчиков назвал ты ещё до того, как тебе начали что-то доказывать:
Вычитал, что в Java вообще нельзя менять директорию в которой исполняется программа, но чё то не верится что разработчики java на столько упоротые.
И следует разделять языки, компилируемые в машинный код, с теми, которые выполняются, по сути, в «песочнице». Тебе же ещё в начале дали ссылок для чтения, но ты видимо не осилил.
Лол. А чё мало что ли? У меня прокрутка в низ улетела, ещё и на английском. Я всё это 30 мин переводить буду. Так что ваши претензии высосаны из пальца.
roy ★★★★★
(16.05.12 16:25:55 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от roy 16.05.12 16:25:55 MSK
По-моему, упоротыми java-разработчиков назвал ты ещё до того, как тебе начали что-то доказывать
Потому, что я не думал, что java действительно не умеет менять current directory, думал такого не может быть. Вот и выразился в такой форме.
Тебе же ещё в начале дали ссылок для чтения, но ты видимо не осилил.
Что вы все этой ссылкой тычите, от того, что я прочитаю, возможности java не изменятся, и область применения не увеличится. Захочу узнать почему так, прочитаю. Буду писать демоны на других ЯП, какие проблемы?
А вот java-программистов эта тема, очевидно, сильно задевает. Раз вы даже на личности начинаете переходить и придумывать мне диагнозы.
★★★★★
(16.05.12 16:45:19 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от yyk 16.05.12 16:11:41 MSK
Постановка задачи где? Иди в пень, боярин…
В первом посте что?
«Как в java менять директорию в которой выполняется процесс?»
Я не знаю как можно сформулировать это предложение проще, чтобы вы смогли его распарсить.
★★★★★
(16.05.12 16:49:06 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от vurdalak 15.05.12 20:25:51 MSK
потому что unmount напишет что filesystem in use
- Ссылка
Ответ на:
комментарий
от TDrive 16.05.12 16:49:06 MSK
Это не постановка задачи «как забить гвоздь?», это вопрос «как вашим сраным электронным микроскопом забить обычный гвоздь?»
yyk ★★★★★
(16.05.12 17:24:34 MSK)
- Показать ответ
- Ссылка
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.
Последнее обновление: 26.04.2018

Класс File, определенный в пакете java.io, не работает напрямую с потоками. Его задачей является управление информацией о файлах и каталогах. Хотя на уровне операционной системы
файлы и каталоги отличаются, но в Java они описываются одним классом File.
В зависимости от того, что должен представлять объект File — файл или каталог, мы можем использовать один из конструкторов для создания объекта:
File(String путь_к_каталогу) File(String путь_к_каталогу, String имя_файла) File(File каталог, String имя_файла)
Например:
// создаем объект File для каталога
File dir1 = new File("C://SomeDir");
// создаем объекты для файлов, которые находятся в каталоге
File file1 = new File("C://SomeDir", "Hello.txt");
File file2 = new File(dir1, "Hello2.txt");
Класс File имеет ряд методов, которые позволяют управлять файлами и каталогами. Рассмотрим некоторые из них:
-
boolean createNewFile(): создает новый файл по пути, который передан в конструктор. В случае удачного создания возвращает
true, иначе false -
boolean delete(): удаляет каталог или файл по пути, который передан в конструктор. При удачном удалении возвращает
true. -
boolean exists(): проверяет, существует ли по указанному в конструкторе пути файл или каталог. И если файл или каталог существует,
то возвращает true, иначе возвращает false -
String getAbsolutePath(): возвращает абсолютный путь для пути, переданного в конструктор объекта
-
String getName(): возвращает краткое имя файла или каталога
-
String getParent(): возвращает имя родительского каталога
-
boolean isDirectory(): возвращает значение true, если по указанному пути располагается каталог
-
boolean isFile(): возвращает значение true, если по указанному пути находится файл
-
boolean isHidden(): возвращает значение true, если каталог или файл являются скрытыми
-
long length(): возвращает размер файла в байтах
-
long lastModified(): возвращает время последнего изменения файла или каталога. Значение представляет количество
миллисекунд, прошедших с начала эпохи Unix -
String[] list(): возвращает массив файлов и подкаталогов, которые находятся в определенном каталоге
-
File[] listFiles(): возвращает массив файлов и подкаталогов, которые находятся в определенном каталоге
-
boolean mkdir(): создает новый каталог и при удачном создании возвращает значение true
-
boolean renameTo(File dest): переименовывает файл или каталог
Работа с каталогами
Если объект File представляет каталог, то его метод isDirectory() возвращает true. И поэтому мы можем получить его
содержимое — вложенные подкаталоги и файлы с помощью методов list() и listFiles(). Получим все подкаталоги и файлы в определенном каталоге:
import java.io.File;
public class Program {
public static void main(String[] args) {
// определяем объект для каталога
File dir = new File("C://SomeDir");
// если объект представляет каталог
if(dir.isDirectory())
{
// получаем все вложенные объекты в каталоге
for(File item : dir.listFiles()){
if(item.isDirectory()){
System.out.println(item.getName() + " t folder");
}
else{
System.out.println(item.getName() + "t file");
}
}
}
}
}
Теперь выполним еще ряд операций с каталогами, как удаление, переименование и создание:
import java.io.File;
public class Program {
public static void main(String[] args) {
// определяем объект для каталога
File dir = new File("C://SomeDir//NewDir");
boolean created = dir.mkdir();
if(created)
System.out.println("Folder has been created");
// переименуем каталог
File newDir = new File("C://SomeDir//NewDirRenamed");
dir.renameTo(newDir);
// удалим каталог
boolean deleted = newDir.delete();
if(deleted)
System.out.println("Folder has been deleted");
}
}
Работа с файлами
Работа с файлами аналогична работе с каталога. Например, получим данные по одному из файлов и создадим еще один файл:
import java.io.File;
import java.io.IOException;
public class Program {
public static void main(String[] args) {
// определяем объект для каталога
File myFile = new File("C://SomeDir//notes.txt");
System.out.println("File name: " + myFile.getName());
System.out.println("Parent folder: " + myFile.getParent());
if(myFile.exists())
System.out.println("File exists");
else
System.out.println("File not found");
System.out.println("File size: " + myFile.length());
if(myFile.canRead())
System.out.println("File can be read");
else
System.out.println("File can not be read");
if(myFile.canWrite())
System.out.println("File can be written");
else
System.out.println("File can not be written");
// создадим новый файл
File newFile = new File("C://SomeDir//MyFile");
try
{
boolean created = newFile.createNewFile();
if(created)
System.out.println("File has been created");
}
catch(IOException ex){
System.out.println(ex.getMessage());
}
}
}
При создании нового файла метод createNewFile() в случае неудачи выбрасывает исключение IOException, поэтому нам надо
его отлавливать, например, в блоке try…catch, как делается в примере выше.
% Path
Интерфейс: java.nio.file.Path
Описание
Представляет собой абстракцию пути к элементу файловой системы (файлу, каталогу или чему-то ещё). Понятие «файловой
системы» здесь можно трактовать достаточно широко, и это не обязательно именно дисковая файловая система. Например,
в стандартной библиотеке есть реализация, представляющая ZIP-архив как файловую систему.
Класс Path предназначен только для манипуляции путями как синтаксическими конструкциями, и вовсе не обязательно, что
файл (или другой элемент ФС), на который указывает путь, действительно существует. Объект Path проще всего
рассматривать как ссылку на элемент ФС, которая сама по себе не умеет работать с тем, на что ссылается. Для операций с
самой ФС используется класс Files, принимающий параметры типа Path.
Здесь мы рассмотрим только операции со стандартной ФС.
Создание путей
Чтобы создать объект типа Path с нуля, используется статический метод get в классе Paths:
static Path get(String first, String... more)
Этот метод принимает один и более компонентов пути, разбивает их на отдельные подкомпоненты по платформозависимым
разделителям (/ для Unix, для Windows), и из полученных компонентов создаёт объект типа Path.
Например, на платформе Windows все приведённые примеры эквивалентны:
Path p1 = Paths.get("C:/windows/explorer.exe"); Path p2 = Paths.get("C:\windows\explorer.exe"); Path p3 = Paths.get("C:\windows", "explorer.exe"); Path p4 = Paths.get("C:", "windows", "explorer.exe");
Обратите внимание, что обратная косая черта должна экранироваться. К сожалению, в Java нет способа отменить
экранирование для более короткой записи Windows-путей.
Объекты класса Path являются неизменяемыми. Все операции с путями возвращают новые объекты Path.
Строковое представление
У класса Path есть вполне привычный метод toString(), возвращающий представление пути в виде строки, используя
системный разделитель компонентов пути.
Path path = Paths.get("C:\windows\system32"); System.out.println(path); // Или, что то же самое: // System.out.println(path.toString())
Результат:
Абсолютные и относительные пути
Приведённый выше пример пути является абсолютным путём, потому что он начинается с корня ФС. Абсолютный путь всегда
однозначно идентифицирует элемент ФС, независимо от того, какой каталог является текущим каталогом программы.
В Unix абсолютные пути начинаются с косой черты, обозначающей корень файловой системы, а в Windows — с буквы
диска. Например, следующие два пути являются абсолютными:
Path unixAbsPath = Paths.get("/usr/bin/firefox"); Path winAbsPath = Paths.get("C:\Program Files\Mozilla Firefox\firefox.exe");
Относительные пути — это пути, ведущие отсчёт от какого-то каталога. По умолчанию при выполнении операций ФС
над относительными путями они разрешаются относительно текущего каталога (current directory), также называемого
рабочим каталогом (working directory). Метод toAbsolutePath() позволяет преобразовать относительный путь в
абсолютный, при этом он разрешается относительно текущего каталога.
Пусть в каталоге /home/user/java лежит файл AbsolutePath.class, откомпилированный из такого файла:
import java.nio.file.Path; import java.nio.file.Paths; public class AbsolutePath { public static void main(String[] args) { Path relPath = Paths.get("lib/opencsv.jar"); Path absPath = relPath.toAbsolutePath(); System.out.println(absPath); } }
Тогда мы получим такой результат при запуске этой программы из командной строки (напомним, что команда cd
устанавливает текущий каталог):
$ cd /home/user/java $ java AbsolutePath /home/user/java/lib/opencsv.jar $ cd /tmp $ java -cp /home/user/java AbsolutePath /tmp/lib/opencsv.jar
При задании относительных путей из соображений переносимости нежелательно использовать разделитель путей Windows
,
если только не известно точно, что программа будет запускаться только под Windows. Windows понимает разделитель путей
Unix/, а вот обратное неверно. Ещё правильнее использовать статический методPaths.getс несколькими параметрами,
чтобы не завязываться на конкретный платформозависимый разделитель, а в случае необходимости всё-таки получить этот
разделитель в виде строки можно воспользоваться методомFileSystem.getSeparator:System.out.println(FileSystem.getDefault().getSeparator()); // Печатает / под Unix и под Windows
Для преобразования относительного пути в абсолютный относительно не текущего каталога, а какого-то другого, можно
воспользоваться методом resolve. Его нужно вызвать у того пути, относительно которого мы разрешаем относительный путь.
У метода resolve есть две версии: одна принимает Path, а вторая принимает String и рассматривает эту строку как
путь, который предстоит разрешить.
Path resolve(Path other)
Path resolve(String other)
Например:
Path configDir = Paths.get("/etc"); System.out.println(configDir.resolve("passwd")); // /etc/passwd Path apacheConf = Paths.get("apache2", "apache2.conf"); System.out.println(configDir.resolve(apacheConf)); // /etc/apache2/apache2.conf
Обратную задачу решает метод relativize, превращающий переданный параметром абсолютный путь в относительный
относительно того пути, у которого этот метод вызывается.
Path relativize(Path other)
Например:
Path homeDir = Paths.get("/home/user"); Path movie = Paths.get("/home/user/Videos/JavaLesson.mkv"); System.out.println(homeDir.relativize(movie)); // Videos/JavaLesson.mkv
Переход вверх и вниз по иерархии ФС
Метод getParent возвращает родительский элемент ФС (как правило, каталог), или null, если такового не существует.
Path getParent()
Например:
System.out.println(Paths.get("C:\windows").getParent()); // C: System.out.println(Paths.get("C:").getParent()); // null
А метод resolve можно использовать не только для абсолютизации путей, но и для получения пути к какому-либо элементу
каталога или какого-то его подкаталога ещё ниже по иерархии ФС:
Paths.get("C:\windows").resolve("explorer.exe") // C:windowsexplorer.exe Paths.get("C:\windows").resolve("system32\user32.dll") // C:windowssystem32user32.dll
Есть также метод resolveSibling, позволяющий получить «сестринский» элемент ФС, то есть разрешающий переданный путь
относительно родительского элемента ФС.
Path resolveSibling(Path other)
Path resolveSibling(String other)
Например, он позволяет получить путь к другому файлу в том же каталоге:
Path dll = Paths.get("C:\windowssystem32\user32.dll") System.out.println(dll.resolveSibling("kernel32.dll") // C:windowssystem32kernel32.dll
Доступ к компонентам пути
Методы getNameCount и getName позволяют пройтись по всем компонентам пути, представленного объектом Path. Эти
компоненты сами имеют тип Path.
int getNameCount()
Path getName(int index)
Например:
Path path = Paths.get("C:\windowsexplorer.exe"); for (int i = 0; i < path.getNameCount(); i++) { System.out.println(path.getName(i)); }
Результат:
Кроме того, класс Path реализует интерфейс Iterable<Path> и, следовательно, поддержку цикла for-each, поэтому то же
самое делает и такой код:
for (Path component: path) { System.out.println(component); }
и даже
path.forEach(System.out::println);
Получение имени файла и каталога
Метод getFileName возвращает путь из одного компонента, соответствующего последнему компоненту исходного пути. Обычно
это имя файла или другого элемента ФС, на который указывает объект Path. Обратите внимание, что этот метод возвращает
Path, а не String.
Path getFileName()
Например:
Paths.get("/home/user/Pictures/kitty.jpg").getFileName() // kitty.jpg Paths.get("C:\gamesWorld of Warcraft").getFileName() // World of Warcraft
Как мы знаем, получить путь к каталогу, в котором находится файл, можно с помощью getParent:
Paths.get("/home/user/Pictures/kitty.jpg").getParent() // /home/user Paths.get("C:\gamesWorld of Warcraft").getParent() // C:games
Работа с расширениями
К сожалению, класс Path сам по себе не предоставляет удобных способов работы с расширениями. В некотором смысле это
логично, ведь понятие расширения существует только для приложений, работающих с файлами, а для самой ФС это всего лишь
часть имени файла. Чтобы отделить расширение, придётся работать с именем файла как со строкой.
Прежде всего эту строку нужно получить:
String fileNameStr = path.getFileName().toString();
После чего работать с расширениями можно обычными строковыми методами:
boolean isPng = fileNameStr.toLowerCase().endsWith(".png");
Обратите внимание на вызов
toLowerCase. Это гарантирует, что мы проверим имя файла на нужное расширение в любом
регистре (.png,.PNG,.Pngи т.д.).
У интерфейса
Pathтоже есть методendsWith, но он проверяет, заканчивается ли путь данным компонентом пути, а не
заканчивается ли строка имени файла данной строкой. Не путайте!Paths.get("/home/user/report.txt").endsWith("report.txt") // true Paths.get("report.txt").endsWith(".txt") // false Paths.get("report.txt").toString().endsWith(".txt") // true
Наконец, можно написать свой метод, который возвращает расширение имени файла или пустую строку, если у имени файла
нет расширения:
public String getExtension(Path path) { String fileNameStr = path.getFileName().toString(); int lastDot = fileNameStr.lastIndexOf('.'); if (lastDot == -1) { return ""; } else { return fileNameStr.substring(lastDot + 1); } }
Взаимодействие со старыми API
Интерфейс Path появился в Java 7. Старые API, спроектированные для Java 6 и ниже, обычно используют вместо него более
старый класс File, существовавший аж в Java 1.0. Он менее удобен, чем Path, потому что поддерживает только
стандартную ФС и нарушает принцип единственности ответственности, сочетая в себе методы для синтаксической манипуляции
путями и методы доступа к ФС.
Если нужно передать объект Path в старое API, используйте метод toFile:
File toFile()
И, получая объекты File из старого API, преобразуйте их в Path:
Path toPath()
К примеру, класс ImageIO, отвечающий за загрузку, сохранение и преобразование изображений, к сожалению, так и не был
обновлён для поддержки параметров типа Path. Вот так с помощью ImageIO можно преобразовать любой поддерживаемый
формат изображений в формат PNG:
Path source = Paths.get("/home/user/Pictures/diagram.bmp"); BufferedImage image = ImageIO.read(source.toFile()); Path dest = Paths.get("/home/user/Pictures/diagram.png"); ImageIO.write(image, "bmp", dest.toFile());



