Utwórz katalog, jeśli nie istnieje, a następnie utwórz pliki również w tym katalogu

113

Warunek jest taki, że jeśli katalog istnieje, to musi tworzyć pliki w tym konkretnym katalogu bez tworzenia nowego katalogu.

Poniższy kod tworzy tylko plik z nowym katalogiem, ale nie dla istniejącego katalogu. Na przykład nazwa katalogu wyglądałaby następująco: „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();
Sri
źródło

Odpowiedzi:

173

Ten kod najpierw sprawdza istnienie katalogu, a jeśli nie, tworzy go, a następnie tworzy plik. Pamiętaj, że nie mogłem zweryfikować niektórych wywołań metod, ponieważ nie mam pełnego kodu, więc zakładam, że wywołania takich rzeczy jak getTimeStamp()i getClassName()będą działać. Powinieneś także zrobić coś z możliwym, IOExceptionktóry może zostać wyrzucony podczas korzystania z którejkolwiek z java.io.*klas - albo twoja funkcja, która zapisuje pliki, powinna zgłosić ten wyjątek (i będzie obsługiwana gdzie indziej), albo powinieneś zrobić to bezpośrednio w metodzie. Założyłem też, że idjest to typ String- nie wiem, ponieważ twój kod nie definiuje go wprost. Jeśli jest to coś innego jak an int, prawdopodobnie powinieneś rzucić go na a Stringprzed użyciem go w fileName, tak jak to zrobiłem tutaj.

Ponadto zamieniłem twoje appendpołączenia na concatlub, +jak uznałem za stosowne.

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);
    }
}

Prawdopodobnie nie powinieneś używać takich nazw ścieżek, jeśli chcesz uruchomić kod w systemie Microsoft Windows - nie jestem pewien, co zrobi z /w nazwach plików. Aby zapewnić pełną przenośność, prawdopodobnie powinieneś użyć czegoś takiego jak File.separator do konstruowania ścieżek.

Edycja : zgodnie z komentarzem JosefScript poniżej, nie jest konieczne testowanie istnienia katalogu. directory.mkdir() Rozmowa powróci truejeśli utworzony katalog, a falsejeśli tak nie jest, w tym przypadku, gdy katalog już istnieje.

Aaron D.
źródło
połączenia działają dobrze. Kiedy próbowałem powyżej kawałek coed, nadal zapisuje plik do PATH, ale nie do katalogu. Użyłem File.seperator do tworzenia nowego pliku.
Sri
Proszę dokładnie wyjaśnić (z nazwami klas i przykładowymi zmiennymi), jakich danych wyjściowych oczekujesz. Załączam mój przykładowy program w całości tutaj pastebin.com/3eEg6jQv , abyś mógł zobaczyć, że robi to, co opisujesz (najlepiej, jak rozumiem).
Aaron D
1
Plik plik = nowy plik (nazwa_katalogu + "/" + nazwa_pliku); Zastąpiłem powyższy fragment kodu StringBuffer fullFilePath = new StringBuffer (nazwa_katalogu) .append (plik.separator) .append (nazwa_pliku); File file = new File (String.valueOf (fullFilePath)); i zadziałało
Sri
W takim przypadku możesz skorzystać z mkdirs()metody.
Aaron D,
3
Dlaczego musisz sprawdzać istnienie katalogu? Bawiłem się tym i o ile widzę, nie wydaje się to robić różnicy, jeśli utworzę ten sam katalog dwa razy. Nawet zawarte pliki nie zostaną nadpisane. Czy coś mi brakuje?
JosefScript,
80

wersja java 8+

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

Plik Files.createDirectories

tworzy nowy katalog i katalogi nadrzędne, które nie istnieją.

Metoda nie zgłasza wyjątku, jeśli katalog już istnieje.

Inês Gomes
źródło
5
To najlepsza odpowiedź
somshivam
Co się stanie, jeśli do tworzenia wymagane jest pozwolenie?
Ajay Takur
Dla Androida Działa tylko na API 26 i nowszych, więc sprawdź tę linię, jeśli (Build.VERSION.SDK_INT> = Build.VERSION_CODES.O) developer.android.com/reference/java/nio/file/ ...
Arpit Patel
24

Staram się, aby było to tak krótkie i proste, jak to tylko możliwe. Tworzy katalog, jeśli nie istnieje, a następnie zwraca żądany plik:

/** 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);
}
Jacob R.
źródło
9
Wolę używać File.separatorChar zamiast „/”.
cactuschibre
23

Sugerowałbym następujące dla Java8 +.

/**
 * Creates a File if the file does not exist, or returns a
 * reference to the File if it already exists.
 */
private File createOrRetrieve(final String target) throws IOException{

    final Path path = Paths.get(target);

    if(Files.notExists(path)){
        LOG.info("Target file \"" + target + "\" will be created.");
        return Files.createFile(Files.createDirectories(path)).toFile();
    }
    LOG.info("Target file \"" + target + "\" will be retrieved.");
    return path.toFile();
}

/**
 * Deletes the target if it exists then creates a new empty file.
 */
private File createOrReplaceFileAndDirectories(final String target) throws IOException{

    final Path path = Paths.get(target);
    // Create only if it does not exist already
    Files.walk(path)
        .filter(p -> Files.exists(p))
        .sorted(Comparator.reverseOrder())
        .peek(p -> LOG.info("Deleted existing file or directory \"" + p + "\"."))
        .forEach(p -> {
            try{
                Files.createFile(Files.createDirectories(p));
            }
            catch(IOException e){
                throw new IllegalStateException(e);
            }
        });

    LOG.info("Target file \"" + target + "\" will be created.");

    return Files.createFile(
        Files.createDirectories(path)
    ).toFile();
}
Pytry
źródło
1
Files.createFile(Files.createDirectories(path)).toFile()powinno być Files.createDirectories(path).toFile()dla Access Deniedrozumu.
Cataclysm,
1
@Pytry, Files.createFile(Files.createDirectories(path))nie działa zgodnie z opisem w komentarzu powyżej. createDirectoriesjuż tworzy katalog z nazwą pliku, np. „test.txt”, dlatego createFilezakończy się niepowodzeniem.
Marcono1234
7

kod:

// 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);


}
Mukesh
źródło
5

Używanie java.nio.Pathgo byłoby całkiem proste -

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);
    }
Saikat
źródło
0

Jeśli tworzysz aplikację internetową, lepszym rozwiązaniem jest sprawdzenie, czy katalog istnieje, a następnie utworzenie pliku, jeśli nie istnieje. Jeśli istnieje, utwórz ponownie.

    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;
   }
Dr X
źródło