【问题标题】:Create a new file with increment values创建一个具有增量值的新文件
【发布时间】:2014-05-24 12:28:42
【问题描述】:

我需要创建一个具有给定名称的文件。

例如,“sampleFile”

如果给定目录中存在这样的文件,那么我想创建附加“1”或“(1)”的文件。

“样本文件1”

有什么办法吗?

我正在寻找一种方法来命名新文件,因为文件夹从不同的系统更新,并且没有增量变量的方法。

例如,int i=1;

文件 f = 新文件(路径);

如果(f.exists()){ f = 新文件(路径+i);

}

我不能采用这种技术,因为如果有一个名为 sample1 的文件,它可能会再次替换它。

根据最新的可用名称,我必须附加下一个值。

例如,如果我有 sample27,我需要程序来理解并创建一个文件作为 sample28

当我们复制文件并粘贴到同一个文件夹中时,Windows 会执行一些操作。我想在我的 Java 程序中复制它

任何帮助表示赞赏:)

干杯!!!

【问题讨论】:

  • 在发布这样的问题之前,请花点时间对 SO 进行一些研究。 Here 是查看目录中是否存在文件的链接。这应该让你开始。
  • 我知道file.exists()的用法,但我的问题不同。我想用递增的值命名新文件。我不能使用变量,因为文件来自不同的系统。
  • 什么意思,不能“使用变量”?请提供更多上下文或显示一些代码。您的问题太含糊,无法提供任何具体答案。
  • 是的。文件名只是一个字符串,因此可以轻松地即时构建。所有你需要的java.io,File class。它有非常方便的createNewFile()方法。
  • 更新了更多信息。

标签: java file file-io directory


【解决方案1】:

让语言为您完成工作。使用 java.nio 包,使用 Path.resolveSibling 方法。给定所需位置和文件名的路径,以及文件名和扩展名(您可以通过 apache FilenameUtils 轻松获得),请执行以下操作:

Path createUniqueFilename(Path destFile, String filename, String extension) {
    Path updatedDestFile = destFile;
    for (int i = 1; Files.exists(updatedDestFile); i++) {
        String newFilename = String.format("%s(%d).%s", filename, i, extension);
        updatedDestFile = destFile.resolveSibling(newFilename);
    }
    return updatedDestFile;
}

【讨论】:

    【解决方案2】:

    你也可以这样用:

    String filename="Sample";
    
    int count=new File("").list(new FilenameFilter() {          
        @Override
        public boolean accept(File dir, String name) {
            if(name.contains(filename)) {
                return true;
            }
            return false;
        }
    }).length;
    
    String nextName=filename+count;
    

    添加额外条件以避免重复

    【讨论】:

      【解决方案3】:

      尝试使用当前日期将其附加到文件名,以便文件名始终是唯一的。

      【讨论】:

        【解决方案4】:

        这会复制文件内容。

        此实现在下面的示例中完美运行(您可以将其复制并粘贴到 java 文件中,它会编译并执行您想要的操作)。唯一的潜在缺点是它会跳过两者之间的“版本”。所以如果它有 A1.txt 和 A3.txt,它只会创建 A4.txt。它也无法处理没有扩展名的文件,但我认为这对你来说并不重要。

        如果文件已经存在,则打印“失败”,否则由于某种原因无法创建文件。

        请注意,您可以在命令行中指定文件目录,否则它将使用当前工作目录。

        它还会递归搜索下面的文件夹,如果您只想搜索当前/指定的文件目录,只需在getFilesForFolder方法中删除return fileMap;之前的else语句即可。

        之前

        ~/当前目录

        • A1.txt
        • A4.txt
        • B1.txt
        • ~/当前目录/asdf
          • A1.txt
          • B1.txt
          • B5.txt

        之后

        ~/当前目录

        • A1.txt
        • A4.txt
        • A5.txt
        • B1.txt
        • B2.txt
        • ~/当前目录/asdf
          • A1.txt
          • A2.txt
          • B1.txt
          • B5.txt
          • B6.txt

        import java.io.File;
        import java.io.IOException;
        import java.io.BufferedWriter;
        import java.io.FileWriter;
        import java.util.ArrayList;
        import java.util.List;
        import java.util.regex.Matcher;
        import java.util.regex.Pattern;
        import java.util.Map;
        import java.util.HashMap;
        import java.io.InputStream;
        import java.io.OutputStream;
        import java.io.FileInputStream;
        import java.io.FileOutputStream;
        
        public class Files {
            static File folder;
            static List<String> files;
        
            public static void main(String[] args) {
                if (args.length > 0)
                    folder = new File(args[0]);
                else
                    folder = new File(System.getProperty("user.dir") + "/testfiles");
        
        
                Map<File, Map<String, Integer>> files = new HashMap<File, Map<String, Integer>>();
                files = getFilesForFolder(folder);
                writeFile(files); 
            }
        
        
            public static void writeFile(Map<File, Map<String, Integer>> files) {
                String fileName;
        
                for (Map.Entry<File, Map<String, Integer>> mapOfMapEntry : files.entrySet()) {
                    File originalFile = mapOfMapEntry.getKey();
                    for (Map.Entry<String, Integer> entry : (mapOfMapEntry.getValue()).entrySet()) {
                        fileName = entry.getKey();
                        try {
                            int i = fileName.contains(".") ? fileName.lastIndexOf('.') : fileName.length();
                            fileName = fileName.substring(0, i) + Integer.toString(entry.getValue() + 1) + fileName.substring(i);
                            File file = new File(fileName);
        
                            if (file.createNewFile()) {
                                System.out.println("Success: " + file.getAbsolutePath());
                                //File originalFile = new File(entry.getKey());
                                InputStream in = new FileInputStream(originalFile);
                                OutputStream out = new FileOutputStream(file);
                                byte[] buffer = new byte[1024];
                                int length;
                                while ((length = in.read(buffer)) > 0) {
                                    out.write(buffer, 0, length);
                                }
                                in.close();
                                out.close();
                            } else {
                                //currently has duplicate value in map
                                //I tried to remove them but it was taking too long to debug
                                //I might come back to it later,
                                //otherwise you're just wasting a bit of computational resources
                                //by trying to create the same file multiple times
                                System.out.println("Failure: " + file.getAbsolutePath());
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            //note this is recursive and will search files
            //in subdirectories. you can change this by removing the else clause before return map
            public static Map<File, Map<String, Integer>> getFilesForFolder(File folder) {
                Map<File, Map<String, Integer>> mapOfMap = new HashMap<File, Map<String, Integer>>();
                Map<String, Integer> fileMap = new HashMap<String, Integer>();
                Integer number;
        
                //any non-digit character 0-inf amount of times, any digit character, 0-inf amount of times, 
                //then a period, then the rest of the extension
                Pattern pattern = Pattern.compile("(\\D*)(\\d*)(\\.\\w*)?"); 
        
        
                //match each file in the file directory with the above regex expr
                for (final File fileEntry : folder.listFiles()) {
                    if (!(fileEntry.isDirectory())) {
                        Matcher m = pattern.matcher(fileEntry.getAbsolutePath());
                        while (m.find()) {
                            number = fileMap.get(m.group(1) + m.group(3));
                            if (number != null) {
                                //the key/value already exist in the filemap
                                //check to see if we should use the new number or not
                                if (Integer.parseInt(m.group(2)) > number) {
                                    fileMap.put(m.group(1) + m.group(3), (Integer.parseInt(m.group(2))));
                                    mapOfMap.put(fileEntry, fileMap);
                                }
                            } else if (!m.group(1).equals("")) {
                                //the map is empty and the file has no number appended to it
                                if (m.group(3) == null) {
                                    fileMap.put(m.group(1), 0);
                                    mapOfMap.put(fileEntry, fileMap);
                                } else {
                                //the map is empty and the file already has a number appended to it
                                    fileMap.put(m.group(1) + m.group(3), (Integer.parseInt(m.group(2))));
                                    mapOfMap.put(fileEntry, fileMap);
                                }
                            }
                        }
                    }
                    else {
                        for (Map.Entry<File, Map<String, Integer>> entry : getFilesForFolder(fileEntry).entrySet()) {
                            mapOfMap.put(entry.getKey(), entry.getValue());
                        }
                    }
                }
                return mapOfMap;
            }
        }
        

        【讨论】:

          【解决方案5】:

          也许你可以试试这样的东西?

          String fileName = "sampleFile";
          String newFilename;
          File f = new File("path" + fileName);
          int version = 1;
          while (f.exists())
          {
                  newFilename= fileName + version;
                  f = new File("path" + newFilename);
                  version++;
          }
          f.mkdirs(); 
          f.createNewFile();
          

          【讨论】:

          • 文件名 1。文件名 12.文件名 123。文件名 1234。等
          • createNewFile() 在循环中应该足够了,因为它有一个 boolean 返回值。
          • 我的问题有点不同。更新了更多信息。
          • @mani_nz 我相信我的算法能够满足您的要求,因为它会在创建新文件之前检查每个可能的版本。假设您有ver1,ver2,ver3,ver5。它创建的文件是ver4。
          • 是的。但我也希望程序读取文件夹中的最高可用版本。因为我有多个系统创建具有不同版本的文件:) 对不起,如果我感到困惑
          猜你喜欢
          • 2018-09-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-04
          相关资源
          最近更新 更多