Create a directory if it does not exist and then create the files in that directory as well
Asked Answered
S

9

233

The condition is if the directory exists it has to create files in that specific directory without creating a new directory.

The below code only creates a file with the new directory but not for the existing directory . For example the directory name would be like "GETDIRECTION":

String PATH = "/remote/dir/server/";
    
String fileName = PATH.append(id).concat(getTimeStamp()).append(".txt");  
             
String directoryName = PATH.append(this.getClassName());   
              
File file  = new File(String.valueOf(fileName));

File directory = new File(String.valueOf(directoryName));

if (!directory.exists()) {
        directory.mkdir();
        if (!file.exists() && !checkEnoughDiskSpace()) {
            file.getParentFile().mkdir();
            file.createNewFile();
        }
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(value);
bw.close();

Salyer answered 9/3, 2015 at 16:38 Comment(0)
H
237

This code checks for the existence of the directory first and creates it if not, and creates the file afterwards. Please note that I couldn't verify some of your method calls as I don't have your complete code, so I'm assuming the calls to things like getTimeStamp() and getClassName() will work. You should also do something with the possible IOException that can be thrown when using any of the java.io.* classes - either your function that writes the files should throw this exception (and it be handled elsewhere), or you should do it in the method directly. Also, I assumed that id is of type String - I don't know as your code doesn't explicitly define it. If it is something else like an int, you should probably cast it to a String before using it in the fileName as I have done here.

Also, I replaced your append calls with concat or + as I saw appropriate.

public void writeFile(String value){
    String PATH = "/remote/dir/server/";
    String directoryName = PATH.concat(this.getClassName());
    String fileName = id + getTimeStamp() + ".txt";

    File directory = new File(directoryName);
    if (! directory.exists()){
        directory.mkdir();
        // If you require it to make the entire directory path including parents,
        // use directory.mkdirs(); here instead.
    }

    File file = new File(directoryName + "/" + fileName);
    try{
        FileWriter fw = new FileWriter(file.getAbsoluteFile());
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write(value);
        bw.close();
    }
    catch (IOException e){
        e.printStackTrace();
        System.exit(-1);
    }
}

You should probably not use bare path names like this if you want to run the code on Microsoft Windows - I'm not sure what it will do with the / in the filenames. For full portability, you should probably use something like File.separator to construct your paths.

Edit: According to a comment by JosefScript below, it's not necessary to test for directory existence. The directory.mkdir() call will return true if it created a directory, and false if it didn't, including the case when the directory already existed.

Hematite answered 9/3, 2015 at 17:24 Comment(7)
the calls are working fine. WHen i tried above piece of coed it is still writing the file to PATH but not to the directory . I have used the File.seperator for the new File creation.Salyer
Please explain exactly (with classnames and sample variables) what output you are expecting. I've attached my example program in full here pastebin.com/3eEg6jQv so you can see that it does what you are describing (as best as I understand).Hematite
File file = new File(directoryName + "/" + fileName); i replaced the code snippet above with StringBuffer fullFilePath = new StringBuffer(directoryName).append(File.separator).append(fileName); File file = new File(String.valueOf(fullFilePath)); and it workedSalyer
In that case you can use the mkdirs() method.Hematite
Why do you have to check for the directory's existence? I played around with this and as far as I can see it does not seem to make a difference, if I create the same directory twice. Even contained files won't get overwritten. Am I missing something?Broeder
No, you're probably not. The problem as asked was to 'create a directory if it doesn't exist', so my code is reflecting that logic, but the JVM's implementation of that call probably won't destroy data if you tell it to create a directory that already exists, so you can call it without the check. If the directory is actually created, the call will return true, otherwise false. I'll add a note to that effect, thank you.Hematite
As far as I know, Java (at least Java 8) is now happy with forward slashes are directory separators in both Windows and (obviously) Linux.Brainy
D
310

Java 8+ version:

import java.nio.file.Paths;
import java.nio.file.Files;

Files.createDirectories(Paths.get("/Your/Path/Here"));

The Files.createDirectories() creates a new directory and parent directories that do not exist. This method does not throw an exception if the directory already exists.

Dorothi answered 17/12, 2019 at 14:12 Comment(7)
What happens if permission is required to create ?Berners
For Android It only works on API 26 and up so Make sure to check this line if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) developer.android.com/reference/java/nio/file/…Up
@AjayTakur If you don't have write permission in the directory you're trying to create the new directory in, it throws an IOExceptionTelegony
How can make a process get the permission to create directory on Windows 10?Oballa
What's the performance of this like - can I use it before every file write?Swihart
But it throws an FileAlreadyExistsException if the path also includes a filename (ends with a filename).Crowns
Please add the import for both Files and for PathsHaletta
H
237

This code checks for the existence of the directory first and creates it if not, and creates the file afterwards. Please note that I couldn't verify some of your method calls as I don't have your complete code, so I'm assuming the calls to things like getTimeStamp() and getClassName() will work. You should also do something with the possible IOException that can be thrown when using any of the java.io.* classes - either your function that writes the files should throw this exception (and it be handled elsewhere), or you should do it in the method directly. Also, I assumed that id is of type String - I don't know as your code doesn't explicitly define it. If it is something else like an int, you should probably cast it to a String before using it in the fileName as I have done here.

Also, I replaced your append calls with concat or + as I saw appropriate.

public void writeFile(String value){
    String PATH = "/remote/dir/server/";
    String directoryName = PATH.concat(this.getClassName());
    String fileName = id + getTimeStamp() + ".txt";

    File directory = new File(directoryName);
    if (! directory.exists()){
        directory.mkdir();
        // If you require it to make the entire directory path including parents,
        // use directory.mkdirs(); here instead.
    }

    File file = new File(directoryName + "/" + fileName);
    try{
        FileWriter fw = new FileWriter(file.getAbsoluteFile());
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write(value);
        bw.close();
    }
    catch (IOException e){
        e.printStackTrace();
        System.exit(-1);
    }
}

You should probably not use bare path names like this if you want to run the code on Microsoft Windows - I'm not sure what it will do with the / in the filenames. For full portability, you should probably use something like File.separator to construct your paths.

Edit: According to a comment by JosefScript below, it's not necessary to test for directory existence. The directory.mkdir() call will return true if it created a directory, and false if it didn't, including the case when the directory already existed.

Hematite answered 9/3, 2015 at 17:24 Comment(7)
the calls are working fine. WHen i tried above piece of coed it is still writing the file to PATH but not to the directory . I have used the File.seperator for the new File creation.Salyer
Please explain exactly (with classnames and sample variables) what output you are expecting. I've attached my example program in full here pastebin.com/3eEg6jQv so you can see that it does what you are describing (as best as I understand).Hematite
File file = new File(directoryName + "/" + fileName); i replaced the code snippet above with StringBuffer fullFilePath = new StringBuffer(directoryName).append(File.separator).append(fileName); File file = new File(String.valueOf(fullFilePath)); and it workedSalyer
In that case you can use the mkdirs() method.Hematite
Why do you have to check for the directory's existence? I played around with this and as far as I can see it does not seem to make a difference, if I create the same directory twice. Even contained files won't get overwritten. Am I missing something?Broeder
No, you're probably not. The problem as asked was to 'create a directory if it doesn't exist', so my code is reflecting that logic, but the JVM's implementation of that call probably won't destroy data if you tell it to create a directory that already exists, so you can call it without the check. If the directory is actually created, the call will return true, otherwise false. I'll add a note to that effect, thank you.Hematite
As far as I know, Java (at least Java 8) is now happy with forward slashes are directory separators in both Windows and (obviously) Linux.Brainy
D
35

Trying to make this as short and simple as possible. Creates directory if it doesn't exist, and then returns the desired file:

/** Creates parent directories if necessary. Then returns file */
private static File fileWithDirectoryAssurance(String directory, String filename) {
    File dir = new File(directory);
    if (!dir.exists()) dir.mkdirs();
    return new File(directory + "/" + filename);
}
Directory answered 31/1, 2018 at 21:9 Comment(1)
Prefer using File.separatorChar instead of "/".Censorious
C
29

I would suggest the following for Java8+.

/**
 * Creates a File if the file does not exist, or returns a
 * reference to the File if it already exists.
 */
public File createOrRetrieve(final String target) throws IOException {
  final File answer;
  Path path = Paths.get(target);
  Path parent = path.getParent();
  if(parent != null && Files.notExists(parent)) {
    Files.createDirectories(path);
  }
  if(Files.notExists(path)) {
    LOG.info("Target file \"" + target + "\" will be created.");
    answer = Files.createFile(path).toFile();
  } else {
    LOG.info("Target file \"" + target + "\" will be retrieved.");
    answer = path.toFile();
  }
  return answer;
}

Edit: Updated to fix bug as indicated by @Cataclysm and @Marcono1234. Thx guys:)

Cuprum answered 15/9, 2017 at 15:48 Comment(2)
Files.createFile(Files.createDirectories(path)).toFile() should be Files.createDirectories(path).toFile() for Access Denied reason.Africanist
@Pytry, Files.createFile(Files.createDirectories(path)) does not work as described in the comment above. createDirectories already creates a directory with the file name, e.g. "test.txt", therefore createFile will fail.Kendrickkendricks
H
11

Simple Solution using using java.nio.Path

public static Path createFileWithDir(String directory, String filename) {
        File dir = new File(directory);
        if (!dir.exists()) dir.mkdirs();
        return Paths.get(directory + File.separatorChar + filename);
    }
Hamite answered 9/1, 2019 at 11:13 Comment(0)
G
9

code:

// Create Directory if not exist then Copy a file.


public static void copyFile_Directory(String origin, String destDir, String destination) throws IOException {

    Path FROM = Paths.get(origin);
    Path TO = Paths.get(destination);
    File directory = new File(String.valueOf(destDir));

    if (!directory.exists()) {
        directory.mkdir();
    }
        //overwrite the destination file if it exists, and copy
        // the file attributes, including the rwx permissions
     CopyOption[] options = new CopyOption[]{
                StandardCopyOption.REPLACE_EXISTING,
                StandardCopyOption.COPY_ATTRIBUTES

        };
        Files.copy(FROM, TO, options);


}
Goldfish answered 5/5, 2017 at 5:31 Comment(0)
P
1

If you create a web based application, the better solution is to check the directory exists or not then create the file if not exist. If exists, recreate again.

    private File createFile(String path, String fileName) throws IOException {
       ClassLoader classLoader = getClass().getClassLoader();
       File file = new File(classLoader.getResource(".").getFile() + path + fileName);

       // Lets create the directory
       try {
          file.getParentFile().mkdir();
       } catch (Exception err){
           System.out.println("ERROR (Directory Create)" + err.getMessage());
       }

       // Lets create the file if we have credential
       try {
           file.createNewFile();
       } catch (Exception err){
           System.out.println("ERROR (File Create)" + err.getMessage());
       }
       return  file;
   }
Prosper answered 14/11, 2019 at 5:40 Comment(0)
J
1

A simple solution using Java 8

public void init(String multipartLocation) throws IOException {
    File storageDirectory = new File(multipartLocation);

    if (!storageDirectory.exists()) {
        if (!storageDirectory.mkdir()) {
            throw new IOException("Error creating directory.");
        }
    }
}
Johnsiejohnson answered 13/6, 2022 at 18:58 Comment(0)
H
1

If you're using Java 8 or above, then Files.createDirectories() method works the best.

Happygolucky answered 17/6, 2022 at 21:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.