Creating file on filesystem with java.io.File - java

I'm trying to create an empty .properties file on my filesystem using java.io.File.
My code is:
File newFile = new File(new File(".").getAbsolutePath() + "folder\\" + newFileName.getText() + ".properties");
if (newFile.createNewFile()){
//do sth...
}
It says that it's impossible to find the specified path.
Printing the Files's constructor's argument it shows correctly the absolute path.
What's wrong?

You can use new File("folder", newFileName.getText() + ".properties") which will create a file reference to the specified file in the folder directory relative to the current working directory
You should make sure that the directory exists before calling createNewFile, as it won't do this for you
For example...
File newFile = new File("folder", newFileName.getText() + ".properties");
File parentFile = newFile.getParentFile();
if (parentFile.exists() || parentFile.mkdirs()) {
if (!newFile.exists()) {
if (newFile.createNewFile()){
//do sth...
} else {
throw new IOException("Could not create " + newFile + ", you may not have write permissions or the file is opened by another process");
}
}
} else {
throw new IOException("Could not create directory " + parentFile + ", you may not have write permissions");
}

I think the "." operator might be causing the error not sure what you are trying to do there, may have misunderstood your intentions but try this instead:
File newFile = new File(new File("folder\\").getAbsolutePath() + ".properties");

Trivially I missed that new File(".").getAbsolutePath() returns the project's absolute path with the . at the end so my folder whould be called as .folder. Next time I'll check twice.

Related

Java get resource is not working

I try to read a resource file from my application but it doesn't work.
Code:
String filename = getClass().getClassLoader().getResource("test.xsd").getFile();
System.out.println(filename);
File file = new File(filename);
System.out.println(file.exists());
Output when I execute the jar-file:
file:/C:/Users/username/Repo/run/Application.jar!/test.xsd
false
It works when I run the application from IntelliJ but not when I execute the jar-file. If I open my jar-file with 7-zip test.xsd is located in the root-folder. Why isn't the code working when I execute the jar-file?
Also, File refers to actual OS file-system files; in the OS's file-system, there is only a jar file, and that jar file is not a folder. You should either extract the contents of the URL to a temporary file, or operate with its bytes in-memory or as a stream.
Note that myURL.getFile() is returning a String representation, and not an actual File. In a similar way, this will not work:
File f = new URL("http://www.example.com/docs/resource1.html").getFile();
f.exists(); // always false - will not be found in the local filesystem
A nice wrapper could be the following:
public static File openResourceAsTempFile(ClassLoader loader, String resourceName)
throws IOException {
Path tmpPath = Files.createTempFile(null, null);
try (InputStream is = loader.getResourceAsStream(resourceName)) {
Files.copy(is, tmpPath, StandardCopyOption.REPLACE_EXISTING);
return tmpPath.toFile();
} catch (Exception e) {
if (Files.exists(tmpPath)) Files.delete(tmpPath);
throw new IOException("Could not create temp file '" + tmpPath
+ "' for resource '" + resourceName + "': " + e, e);
}
}

Moving/Copying a file to another directory creates empty file and empties source

My goal is to move a file from one directory to another. The source is on a local drive and the destination is on a network drive. It doesn't matter whether I move or I copy then delete source. The file is approx 6GB.
What I've tried:
// C:\path\to\dir\file.bak
File source = new File(localRoot + backup);
// \\192.168.1.100\path\to\dir\file.bak
File dest = new File(storageRoot + "/" + storagePath + "/" + backup);
try {
log("Copying");
// I've tried copyFile as well.
FileUtils.copyFileToDirectory(source, dest);
log("copied");
} catch (Exception e) {
e.printStackTrace();
}
File source = new File(localRoot + backup);
File dest = new File(storageRoot + "/" + storagePath + "/" + backup);
try {
log("Copying");
// I've tried move and creating Paths instead of Files as well.
Files.copy(source.toPath(), dest.toPath());
log("copied")
} catch (Exception e) {
e.printStackTrace();
}
I've tried as well a manual method using Input, OutputStreams and reading bytes.
The results is that a file is created in the destination with the correct filename with 0 bytes, and the source file is rewritten from 6GB to 0 bytes. This happens for all methods I've tried, the only exception is that when I tried move, the source file was deleted rather than rewritten.
All code is in early development, please refrain from commenting on best practices.
Thank you, and what am I missing or what else can I try?

Download entire FTP directory in Java (Apache Net Commons)

I am trying to recursively iterate through the entire root directory that I arrive at after login to the FTP server.
I am able to connect, all I really want to do from there is recurse through the entire structure and and download each file and folder and have it in the same structure as it is on the FTP. What I have so far is a working download method, it goes to the server and gets my entire structure of files, which is brilliant, except it fails on the first attempt, then works the second time around. The error I get is as follows:
java.io.FileNotFoundException: output-directory\test\testFile.png
(The system cannot find the path specified)
I managed to do upload functionality of a directory that I have locally, but can't quite get downloading to work, after numerous attempts I really need some help.
public static void download(String filename, String base)
{
File basedir = new File(base);
basedir.mkdirs();
try
{
FTPFile[] ftpFiles = ftpClient.listFiles();
for (FTPFile file : ftpFiles)
{
if (!file.getName().equals(".") && !file.getName().equals("..")) {
// If Dealing with a directory, change to it and call the function again
if (file.isDirectory())
{
// Change working Directory to this directory.
ftpClient.changeWorkingDirectory(file.getName());
// Recursive call to this method.
download(ftpClient.printWorkingDirectory(), base);
// Create the directory locally - in the right place
File newDir = new File (base + "/" + ftpClient.printWorkingDirectory());
newDir.mkdirs();
// Come back out to the parent level.
ftpClient.changeToParentDirectory();
}
else
{
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
String remoteFile1 = ftpClient.printWorkingDirectory() + "/" + file.getName();
File downloadFile1 = new File(base + "/" + ftpClient.printWorkingDirectory() + "/" + file.getName());
OutputStream outputStream1 = new BufferedOutputStream(new FileOutputStream(downloadFile1));
boolean success = ftpClient.retrieveFile(remoteFile1, outputStream1);
outputStream1.close();
}
}
}
}
catch(IOException ex)
{
System.out.println(ex);
}
}
Your problem (well, your current problem after we got rid of the . and .. and you got past the binary issue) is that you are doing the recursion step before calling newDir.mkdirs().
So suppose you have a tree like
.
..
someDir
.
..
someFile.txt
someOtherDir
.
..
someOtherFile.png
What you do is skip the dot files, see that someDir is a directory, then immediately go inside it, skip its dot files, and see someFile.txt, and process it. You have not created someDir locally as yet, so you get an exception.
Your exception handler does not stop execution, so control goes back to the upper level of the recursion. At this point it creates the directory.
So next time you run your program, the local someDir directory is already created from the previous run, and you see no problem.
Basically, you should change your code to:
if (file.isDirectory())
{
// Change working Directory to this directory.
ftpClient.changeWorkingDirectory(file.getName());
// Create the directory locally - in the right place
File newDir = new File (base + "/" + ftpClient.printWorkingDirectory());
newDir.mkdirs();
// Recursive call to this method.
download(ftpClient.printWorkingDirectory(), base);
// Come back out to the parent level.
ftpClient.changeToParentDirectory();
}
A complete standalone code to download all files recursively from an FTP folder:
private static void downloadFolder(
FTPClient ftpClient, String remotePath, String localPath) throws IOException
{
System.out.println("Downloading folder " + remotePath + " to " + localPath);
FTPFile[] remoteFiles = ftpClient.listFiles(remotePath);
for (FTPFile remoteFile : remoteFiles)
{
if (!remoteFile.getName().equals(".") && !remoteFile.getName().equals(".."))
{
String remoteFilePath = remotePath + "/" + remoteFile.getName();
String localFilePath = localPath + "/" + remoteFile.getName();
if (remoteFile.isDirectory())
{
new File(localFilePath).mkdirs();
downloadFolder(ftpClient, remoteFilePath, localFilePath);
}
else
{
System.out.println("Downloading file " + remoteFilePath + " to " +
localFilePath);
OutputStream outputStream =
new BufferedOutputStream(new FileOutputStream(localFilePath));
if (!ftpClient.retrieveFile(remoteFilePath, outputStream))
{
System.out.println("Failed to download file " + remoteFilePath);
}
outputStream.close();
}
}
}
}

How to create a directory and sub directory structure with java?

Hello there I want to create the directories and sub directories with the java.
My directory structure is starts from the current application directory, Means in current projects directory which looks like following...
Images
|
|+ Background
|
|+ Foreground
|
|+Necklace
|+Earrings
|+Etc...
I know how to create directory but I need to create sub directory I tried with following code what should be next steps ?
File file = new File("Images");
file.mkdir();
You can use File.mkdir() or File.mkdirs() to create a directory. Between the two, the latter method is more tolerant and will create all intermediate directories as needed. Also, since I see that you use "\\" in your question, I would suggest using File.separator for a portable path separator string.
Starting from Java 7, you can use the java.nio.file.Files & java.nio.file.Paths classes.
Path path = Paths.get("C:\\Images\\Background\\..\\Foreground\\Necklace\\..\\Earrings\\..\\Etc");
try {
Files.createDirectories(path);
} catch (IOException e) {
System.err.println("Cannot create directories - " + e);
}
This is a tricky solution (because I used only one path to go to the whole structure).
If you don't like tricky solutions, you can use 4 simple paths instead:
Path p1 = Paths.get("C:\\Images\\Background");
Path p2 = Paths.get("C:\\Images\\Foreground\\Necklace");
Path p3 = Paths.get("C:\\Images\\Foreground\\Earrings");
Path p4 = Paths.get("C:\\Images\\Foreground\\Etc");
and then call the createDirectories method for all of them:
Files.createDirectories(p1);
Files.createDirectories(p2);
Files.createDirectories(p3);
Files.createDirectories(p4);
You can create all parent directories by using File.mkdirs().
File.mkdirs() - Creates the directory named by this abstract pathname, including any necessary but nonexistent parent directories. Note that if this operation fails it may have succeeded in creating some of the necessary parent directories.
You could do it with File#mkdirs() and something like,
// The "/" is cross-platform safe as a path-separator in Java.
// So is "\\" but that's twice the characters!
String path = createImages.getAbsolutePath() + "/Images";
File f = new File(path);
if (!f.isDirectory()) {
boolean success = f.mkdirs();
if (success) {
System.out.println("Created path: " + f.getPath());
} else {
System.out.println("Could not create path: " + f.getPath());
}
} else {
System.out.println("Path exists: " + f.getPath());
}
Per the linked Javadoc,
Creates the directory named by this abstract pathname, including any necessary but nonexistent parent directories. Note that if this operation fails it may have succeeded in creating some of the necessary parent directories.
You can just use file.mkdirs(), it will create sub-directory.
String path = images + File.separator + Background + File.separator + Foreground + File.separator + Necklace + File.separator + Earrings ;
File file = new File( path );
file.mkdirs();
Adding up to #ROMANIA_engineer's answer..
I used Path.resolve() method to create sub-directories using variables lika DateTime and others:
private final Path root = Paths.get("target\\");
private final Path batchFilePath = Paths.get(root.resolve(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyymmdd_HHmmss"))).toString());
Files.createDirectory(root);
Files.createDirectory(batchFilePath);
And the result was:
directory/subdirectory example

Determine whether a folder is present?

How would I go about determining whether a file or directory has been created in Java?
I basically want to create a data directory if one is not already present.
Thanks.
You can call File#exists() to determine if it exists, but you can also just call File#mkdirs() to automatically create the whole path if not exist.
I usually use this technique:
File folderLocation = new File("/blah/blah/mysystem/myfolder");
if (folderLocation.exists()) {
if (!folderLocation .isDirectory()) {
throw new IOException("File-system item with path [" + folderLocation.getAbsolutePath() + "] exists but is not a folder.");
}
} else {
if (!folderLocation.mkdirs()) {
throw new IOException("Could not create folder with path : " + folderLocation.getAbsolutePath());
}
}
// we are guaranteed that the folder exists here

Categories

Resources