Tạo một thư mục nếu nó không tồn tại và sau đó tạo các tệp trong thư mục đó


113

Điều kiện là nếu thư mục tồn tại, nó phải tạo tệp trong thư mục cụ thể đó mà không tạo thư mục mới.

Đoạn mã dưới đây chỉ tạo một tệp với thư mục mới nhưng không tạo cho thư mục hiện có. Ví dụ: tên thư mục sẽ giống như "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();

Câu trả lời:


172

Mã này kiểm tra sự tồn tại của thư mục trước tiên và tạo nó nếu không, và tạo tệp sau đó. Xin lưu ý rằng tôi không thể xác minh một số lệnh gọi phương thức của bạn vì tôi không có mã hoàn chỉnh của bạn, vì vậy tôi giả định rằng các lệnh gọi đến những thứ như getTimeStamp()getClassName()sẽ hoạt động. Bạn cũng nên làm điều gì đó với khả năng IOExceptioncó thể được ném ra khi sử dụng bất kỳ java.io.*lớp nào - hoặc hàm ghi tệp của bạn sẽ ném ngoại lệ này (và nó được xử lý ở nơi khác) hoặc bạn nên thực hiện trực tiếp trong phương thức. Ngoài ra, tôi đã giả định rằng đó idlà loại String- tôi không biết vì mã của bạn không xác định rõ ràng nó. Nếu nó là một cái gì đó khác giống như một int, bạn có thể nên chuyển nó sang a Stringtrước khi sử dụng nó trong fileName như tôi đã làm ở đây.

Ngoài ra, tôi đã thay thế các appendcuộc gọi của bạn bằng concathoặc +khi tôi thấy thích hợp.

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

Bạn có thể không nên sử dụng các tên đường dẫn trống như thế này nếu bạn muốn chạy mã trên Microsoft Windows - Tôi không chắc nó sẽ làm gì với tên /trong tên tệp. Để có tính di động đầy đủ, bạn có thể nên sử dụng một cái gì đó như File.separator để xây dựng đường dẫn của mình.

Chỉnh sửa : Theo nhận xét của JosefScript bên dưới, không cần thiết phải kiểm tra sự tồn tại của thư mục. Cuộc directory.mkdir() gọi sẽ trả về truenếu nó đã tạo một thư mục và falsenếu không, bao gồm cả trường hợp thư mục đã tồn tại.


các cuộc gọi đang hoạt động tốt. KHI tôi đã thử đoạn mã ở trên, nó vẫn ghi tệp vào PATH nhưng không vào thư mục. Tôi đã sử dụng File.seperator để tạo Tệp mới.
Sri

Vui lòng giải thích chính xác (với tên lớp và biến mẫu) bạn đang mong đợi kết quả đầu ra nào. Tôi đã đính kèm toàn bộ chương trình ví dụ của mình tại đây pastebin.com/3eEg6jQv để bạn có thể thấy rằng nó thực hiện những gì bạn đang mô tả (tốt nhất theo tôi hiểu).
Aaron D

1
File file = new File (directoryName + "/" + fileName); tôi đã thay thế đoạn mã ở trên bằng StringBuffer fullFilePath = new StringBuffer (directoryName) .append (File.separator) .append (fileName); File file = new File (String.valueOf (fullFilePath)); và nó đã hoạt động
Sri vào

Trong trường hợp đó, bạn có thể sử dụng mkdirs()phương pháp.
Aaron D

3
Tại sao bạn phải kiểm tra sự tồn tại của thư mục? Tôi đã thử với cái này và theo như tôi thấy thì nó dường như không tạo ra sự khác biệt, nếu tôi tạo cùng một thư mục hai lần. Ngay cả các tệp được chứa cũng sẽ không bị ghi đè. Tui bỏ lỡ điều gì vậy?
JosefScript

78

phiên bản java 8+

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

Files.createDirectories

tạo một thư mục mới và các thư mục mẹ không tồn tại.

Phương thức không ném một ngoại lệ nếu thư mục đã tồn tại.


5
Đây là câu trả lời hay nhất
somshivam

Điều gì xảy ra nếu cần có quyền để tạo?
Ajay Takur

Đối với Android Nó chỉ hoạt động trên API 26 trở lên vì vậy, hãy nhớ kiểm tra dòng này nếu (Build.VERSION.SDK_INT> = Build.VERSION_CODES.O) developer.android.com/reference/java/nio/file/…
Arpit Patel

24

Cố gắng làm cho điều này càng ngắn gọn và đơn giản càng tốt. Tạo thư mục nếu nó không tồn tại, sau đó trả về tệp mong muốn:

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

9
Thích sử dụng File.separatorChar thay vì "/".
cactuschibre

23

Tôi sẽ đề xuất những điều sau cho 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();
}

1
Files.createFile(Files.createDirectories(path)).toFile()nên Files.createDirectories(path).toFile()cho Access Deniedlý do.
hồng thủy

1
@Pytry, Files.createFile(Files.createDirectories(path))không hoạt động như mô tả trong nhận xét ở trên. createDirectoriesđã tạo một thư mục với tên tệp, ví dụ: "test.txt", do đó createFilesẽ không thành công.
Marcono1234

7

mã:

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


}

5

Sử dụng java.nio.Pathnó sẽ khá đơn giản -

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

0

Nếu bạn tạo một ứng dụng dựa trên web, giải pháp tốt hơn là kiểm tra thư mục có tồn tại hay không sau đó tạo tệp nếu không tồn tại. Nếu tồn tại, hãy tạo lại một lần nữa.

    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;
   }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.