【问题标题】:Delete files before creating new from temp using Java file method在使用 Java 文件方法从 temp 创建新文件之前删除文件
【发布时间】:2020-06-22 14:46:34
【问题描述】:

我有下面的代码,我试图在temp 目录中创建新文件,该目录是xml 文件,并且工作正常。

现在每次我运行代码时,我想在创建新的 xml 文件之前从这个 temp 目录中删除以前的 xml 文件,因为 xml 文件的大小很大,它可能会填满我的临时空间。 xml 文件有一定的命名约定life__*.xml。所以它应该删除所有life__*.xml 文件。

我不确定我们是否可以在此处使用tempFile.deleteOnExit() 或如何使用它,因为我在 java 文件处理方面还很陌生,不知道在代码中更改什么以及在哪里进行更改:

*/
@Slf4j
public class InputConsumer implements Runnable {

    public static final String XML_SUFFIX = ".xml";

    private void processlifeZipFile() {        //check the number of line in xml input zip file processed
        final AtomicBoolean isInsideLeiRecord = new AtomicBoolean();
        isInsideLeiRecord.set(false);
        final StringBuilder currentLeiRecordXml = new StringBuilder();
        try (FileSystem zipFs = FileSystems.newFileSystem(jobRunner.getInputZipPath(), null);   //check the zip file
             Stream<String> lines = Files.lines(xmlFileFromLeiZipFile(zipFs))) {  //streaming the lines inside xml file
            AtomicInteger processedLinesCounter = new AtomicInteger();
            AtomicInteger currentLineNumber = new AtomicInteger();
            lines
                    .sequential()
                    .forEach(handleLineAndIncrementLineNumber(isInsideLeiRecord, currentLeiRecordXml, processedLinesCounter, currentLineNumber))
            ;
            log.info("{} lines of XML file inside life input ZIP file {} processed.", processedLinesCounter.get(), jobRunner.getInputZipPath() //number of lines processed in xml file
            );
        } catch (IOException e) {
            throw new IllegalStateException("Problem reading input file at " + jobRunner.getInputZipPath() + ".", e);
        }
    }
    private Path xmlFileFromLeiZipFile(FileSystem zipFs) {       //extracts the xml file from zip file
        log.info("Input file {} exists: {}", jobRunner.getInputZipPath(), Files.exists(jobRunner.getInputZipPath()));
        Path tmpXmlPath = createTmpXmlFile("life__" + System.currentTimeMillis());
        for (Path rootDir : zipFs.getRootDirectories()) {
            try (Stream<Path> files = treeAt(rootDir)) {
                log.info("Trying to extract life XML file from ZIP file into {}.", tmpXmlPath);
                final Path xmlFileInsideZip = files
                        .filter(isNotADir())
                        .filter(Files::isRegularFile)
                        .findFirst()
                        .orElseThrow(() -> new IllegalStateException("No file found in LEI ZIP file."));
                log.info("Path to life XML file inside ZIP file: {}.", xmlFileInsideZip);
                return copyReplacing(xmlFileInsideZip, tmpXmlPath);
            }
        }
        throw new IllegalStateException("No file found in LEI ZIP file " + jobRunner.getInputZipPath() + ".");
    }
    

    private static Path createTmpXmlFile(final String prefix) {
        try {
            log.info("Creating temporary file {}{}", prefix, XML_SUFFIX);
            return Files.createTempFile(prefix, XML_SUFFIX);
        } catch (IOException e) {
            throw new IllegalStateException("Could not create tmp file at " + prefix + XML_SUFFIX + ". ", e);
        }
    }
    
    @NotNull
    private static Path copyReplacing(Path from, Path to) {
        requireNonNull(from, "Trying to copy from a path, which is null to path " + to + ".");   //trying to copy file where no xml file exist in root directory
        requireNonNull(to, "Trying to copy from path " + from + " to a path, which is null.");
        try {
            return Files.copy(from, to, REPLACE_EXISTING);
        } catch (IOException e) {
            throw new IllegalStateException("Cannot copy from " + from + " to " + to + ". ", e);
        }
    }
}

【问题讨论】:

  • deleteOnExit 仅在 JVM 退出时执行删除。使用路径创建一个文件对象,并在完成复制后调用 .delete() 。然后返回副本
  • 你能提一下做同样事情的代码吗..它真的很有帮助,因为我尝试了同样的方法,但还没有运气..

标签: java xml file-handling tempdir


【解决方案1】:
Andrew, Please try the below code change done in method processlifeZipFile() and see if it works.

private void processlifeZipFile() {        //check the number of line in xml input zip file processed
        final AtomicBoolean isInsideLeiRecord = new AtomicBoolean();
        isInsideLeiRecord.set(false);
        final StringBuilder currentLeiRecordXml = new StringBuilder();
        Object jobRunner;
        try (FileSystem zipFs = FileSystems.newFileSystem(jobRunner.getInputZipPath(), null);   //check the zip file
                java.nio.file.Path tmpXMLFilePath = xmlFile`enter code here`FromLeiZipFile(zipFs); // Change
             Stream<String> lines = Files.lines(tmpXMLFilePath)) {  //streaming the lines inside xml file
            AtomicInteger processedLinesCounter = new AtomicInteger();
            AtomicInteger currentLineNumber = new AtomicInteger();
            lines
                    .sequential()
                    .forEach(handleLineAndIncrementLineNumber(isInsideLeiRecord, currentLeiRecordXml, processedLinesCounter, currentLineNumber))
            ;
            log.info("{} lines of XML file inside life input ZIP file {} processed.", processedLinesCounter.get(), jobRunner.getInputZipPath() //number of lines processed in xml file
            );
            Files.delete(tmpXMLFilePath); // change
        } catch (IOException e) {
            throw new IllegalStateException("Problem reading input file at " + jobRunner.getInputZipPath() + ".", e);
        }
    }

编辑---->

我创建了一个新方法来删除除了新的临时 xml 文件之外的所有其他文件。

void deleteXMLFiles(Path xmlPath) {
        try {
            final List<Path> pathsToDelete = Files.list(xmlPath.getParent()).sorted(Comparator.reverseOrder()).collect(Collectors.toList());
            for(Path path : pathsToDelete) {
                if (path.equals(xmlPath)) {
                    System.out.println("Skipping newly created XML file");
                    continue;
                }
                Files.delete(path);
                System.out.println("Deleting -> " + path.toString());
            }
        }catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }

将“Files.delete(tmpXMLFilePath); // change”行替换为以tmpXMLFilePath为参数调用新创建的方法。

删除XMLFiles(tmpXMLFilePath);

更多详情请参考此答案:https://stackoverflow.com/a/47994874/13677537

编辑 2 ---->

修改deleteXMLFiles()方法以在删除前检查文件名模式:

void deleteXMLFiles(Path xmlPath) {
        try {
            final List<Path> pathsToDelete = Files.list(xmlPath).sorted(Comparator.reverseOrder()).collect(Collectors.toList());
            for (Path path : pathsToDelete) {
                String xmlFileName = path.toString();
                if (Pattern.matches(".*life__.*.xml", xmlFileName)) {
                    Files.delete(path);
                    System.out.println("Deleting -> " + xmlFileName);
                }
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

修改了 processlifeZipFile() 方法调用以在创建新文件之前删除临时 XML 文件:

private void processlifeZipFile() {        //check the number of line in xml input zip file processed
        final AtomicBoolean isInsideLeiRecord = new AtomicBoolean();
        isInsideLeiRecord.set(false);
        final StringBuilder currentLeiRecordXml = new StringBuilder();
        
        // Delete the old temp XML Files before starting the processing
        deleteXMLFiles(Paths.get(System.getProperty("java.io.tmpdir")));
        
        try (FileSystem zipFs = FileSystems.newFileSystem(jobRunner.getInputZipPath(), null);   //check the zip file
             Stream<String> lines = Files.lines(xmlFileFromLeiZipFile(zipFs))) {  //streaming the lines inside xml file
            AtomicInteger processedLinesCounter = new AtomicInteger();
            AtomicInteger currentLineNumber = new AtomicInteger();
            lines
                    .sequential()
                    .forEach(handleLineAndIncrementLineNumber(isInsideLeiRecord, currentLeiRecordXml, processedLinesCounter, currentLineNumber))
            ;
            log.info("{} lines of XML file inside life input ZIP file {} processed.", processedLinesCounter.get(), jobRunner.getInputZipPath() //number of lines processed in xml file
            );
        } catch (IOException e) {
            throw new IllegalStateException("Problem reading input file at " + jobRunner.getInputZipPath() + ".", e);
        }
    }

【讨论】:

  • 请替换行“Files.delete(tmpXMLFilePath);”使用以下行:“log.info(”临时文件已删除:“+ Files.deleteIfExists(tmpXMLFilePath));”并尝试。
  • 它实际上删除了正在创建的错误文件,而不是所有以前的 xml 文件
  • 谢谢我现在检查但一个问题,因为我只想删除 life__*.xml 文件,因为它是由这个过程创建的,我认为这个逻辑将从 tmp 目录中删除所有 *.xml 文件文件夹?
  • 我刚试过......它试图从临时目录中删除所有其他文件,不包括 life__*.xml 文件
  • 检查答案的 EDIT 2 部分中给出的更改
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-15
  • 2017-06-05
  • 2021-12-07
  • 1970-01-01
  • 2013-10-29
  • 1970-01-01
相关资源
最近更新 更多