使用 Java 文件方法从临时创建新文件之前删除文件

Delete files before creating new from temp using Java file method

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

现在每次我 运行 代码时,我想在创建新的 xml 文件之前从这个 temp 目录中删除以前的 xml 文件,因为xml 文件很大,它可能会填满我的临时文件 space。 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);
        }
    }
}
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 作为参数调用新创建的方法。

删除XML文件(tmpXML文件路径);

更多详情请参考此答案:

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