2

特定のディレクトリからファイルを読み取って処理し、処理したらファイルをアーカイブディレクトリに移動するコードを以下に示します。これはうまくいっています。毎日新しいファイルを受信して​​おり、Control-M スケジューラ ジョブを使用してこのプロセスを実行しています。

次の実行では、その特定のディレクトリから新しいファイルを再度読み取り、このファイルをアーカイブディレクトリ内のファイルでチェックします。コンテンツが異なる場合はファイルのみを処理し、それ以外は何もしません。このジョブを実行するために記述されたシェル スクリプトがあり、このプロセスのログは表示されません。

ファイルが特定のディレクトリと同一である場合、Javaコードでログメッセージを生成し、アーカイブディレクトリで「ファイルが同一である」というログを生成したいと考えています。しかし、これを行う方法が正確にはわかりません。ファイル内の何かを処理または移動するためのロジックを書きたくありません..ファイルが等しいことを確認し、そうであればログメッセージを生成するだけです。私が受け取ったファイルはそれほど大きくなく、最大サイズは 10MB までです。

以下は私のコードです:

        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(".archive.dir"));
            Files.move(inputFile, archiveDir.resolve(inputFile.getFileName()),StandardCopyOption.REPLACE_EXISTING);
        }
        return true;
    }

    private void readFile(String inputFile) throws IOException, FileNotFoundException {
        log.info("Import " + 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 Complete");
    }       

}
4

1 に答える 1

1

ファイルのサイズやパフォーマンスのニーズに関する限られた情報に基づいて、このようなことを行うことができます。これは 100% 最適化されていない可能性がありますが、単なる例です。新しいメソッドが 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"));  

for(Path inputFile : pathsToProcess) {

    // 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 read, process in DB and move the file over to the archive. 
    else {
        // read in the file:
        readFile(inputFile.toAbsolutePath().toString());
        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;
    }
于 2020-01-24T12:05:15.867 に答える