如果两个文件相同,并且在Java中具有相同的内容,则提供日志

问题描述 投票:2回答:1

我有以下代码,其中我从特定目录中读取文件,对其进行处理,一旦处理,我将文件移至存档目录。一切正常。我每天都会收到新文件,并且正在使用Control-M调度程序作业来运行此过程。

现在,在下一次运行中,我将从该特定目录中再次读取新文件,并与存档目录中的文件一起检查此文件,如果内容不同,则仅处理该文件,否则不做任何事情。有编写此操作的shell脚本,我们看不到此过程的任何日志。

现在,如果文件在特定目录中相同,则我想在我的Java代码中生成日志消息,然后在存档目录中生成'文件相同'的日志。但是我不知道该怎么做。我不想编写逻辑来处理或移动文件中的任何内容。我只需要检查文件是否相等以及是否相等即可。产生日志消息。我收到的文件不是很大,最大大小可以到10MB。

下面是我的代码:

public class ImportWorkflow extends AbstractWorkflow {
    private static final String INPUT_DIR_ARGUMENT = "inputDir";
    private final static Logger log = LoggerFactory.getLogger(ImportWorkflow.class);
    /**
     * For reading in a single  file:
     */
    private Importer Importer;

    @Override
    public boolean run(CommandLine commandLine) throws Exception {
        AnnotationConfigApplicationContext applicationContext = initializeApplicationContext();

        String inputFileDirectory = commandLine.getOptionValue(INPUT_DIR_ARGUMENT);

        if (inputFileDirectory == null) {
            log.error("The input file directory has not been specified");
            return false;
        }

        Importer = applicationContext.getBean(Importer.class);

        Path inputDirectory = Paths.get(inputFileDirectory);
        SortedSet<Path> pathsToProcess = new TreeSet<Path>();
        try(DirectoryStream<Path> directoryStream = Files.newDirectoryStream(inputDirectory)){
            for (Path fileToWork : directoryStream) {
                if(fileToWork.toString().endsWith(".out.gz") || fileToWork.toString().endsWith(".px.gz")) {
                    pathsToProcess.add(fileToWork);
                }else {
                    log.warn("Datei wird ignoriert: " + fileToWork);
                }
            }
        }
        for(Path inputFile : pathsToProcess) {
            // read in the file:
            readFile(inputFile.toAbsolutePath().toString());
            // move the file away into the archive:
            Path archiveDir = Paths.get(applicationContext.getEnvironment().getProperty("betl..archive.dir"));
            Files.move(inputFile, archiveDir.resolve(inputFile.getFileName()),StandardCopyOption.REPLACE_EXISTING);
        }
        return true;
    }

    private void readFile(String inputFile) throws IOException, FileNotFoundException {
        log.info("Importiere Daten aus der Datei " + inputFile);

        try (InputStream is = new FileInputStream(inputFile);
                Reader underlyingReader = inputFile.endsWith("gz")
                        ? new InputStreamReader(new GZIPInputStream(is), DEFAULT_CHARSET)
                        : new InputStreamReader(is, DEFAULT_CHARSET);
                BufferedReader reader = new BufferedReader(underlyingReader)) {

            if (isPxFile(inputFile)) {
                Importer.processField(reader, tablenameFromFilename(inputFile));
            } else {
                Importer.processFile(reader, tablenameFromFilename(inputFile)); 
            }

        }
        log.info("Import abgeschlossen");
    }

    private boolean isPxFile(String inputFile) {
        return inputFile.contains(".px.gz");
    }

    private String tablenameFromFilename(String path) {
        String filename = Paths.get(path).getFileName().toString();
        System.out.println(filename.substring(0, filename.lastIndexOf('.')));

        return "BB_" + filename.substring(0, filename.indexOf('.')).toUpperCase() + "_IMPORT";
    }

    @Override
    public void addOptions(Options options) {
        options.addOption(null, INPUT_DIR_ARGUMENT, true, "(bbgimport) specifies the input directory");
    }

}
java logging file-handling readfile file-diffs
1个回答
1
投票

基于关于文件大小或性能需求的有限信息,可以执行类似的操作。这可能不是100%优化的,而仅仅是一个例子。您可能还必须在main方法中进行一些异常处理,因为新方法可能会抛出IOException:

import org.apache.commons.io.FileUtils;  // Add this import statement at the top


// --> Moved this statement outside the for loop, as it seems there is no need to fetch the archive directory path multiple times.
Path archiveDir = Paths.get(applicationContext.getEnvironment().getProperty("betl..archive.dir"));  

// This is your existing for loop but with changes that I did
for(Path inputFile : pathsToProcess) {

    // read in the file:
    readFile(inputFile.toAbsolutePath().toString());  //existing code
    // move the file away into the archive:

    // Added this code
    if(checkIfFileMatches(inputFile, archiveDir); {
        // Add the logger here.
    }

    //Added the else condition, so that if the files do not match, only then you move the file over to the archive. 
    else {
        Files.move(inputFile, archiveDir.resolve(inputFile.getFileName()),StandardCopyOption.REPLACE_EXISTING);
    }


//Added this method to check if the source file and the target file contents are same.
// This will need an import of the FileUtils class. You may change the approach to use any other utility file, or read the data byte by byte and compare. If the files are very large, probably better to use Buffered file reader.
    private boolean checkIfFileMatches(Path sourceFilePath, Path targetDirectoryPath) throws IOException {
        if (sourceFilePath != null) {  // may not need this check
            File sourceFile = sourceFilePath.toFile();
            String fileName = sourceFile.getName();

            File targetFile = new File(targetDirectoryPath + "/" + fileName);

            if (targetFile.exists()) {
                return FileUtils.contentEquals(sourceFile, targetFile);
            }
        }
        return false;
    }
© www.soinside.com 2019 - 2024. All rights reserved.