Bandingkan folder java – panduan menggunakan GroupDocs.Comparison

Pernah menghabiskan berjam‑jam memeriksa secara manual file mana yang berubah antara dua versi proyek? Anda tidak sendirian. GroupDocs.Comparison untuk Java membuat tugas membosankan ini menjadi mudah dengan memungkinkan Anda membandingkan dua folder dengan satu panggilan API. Dalam tutorial ini Anda akan belajar cara membandingkan folder java secara efektif, mulai dari penyiapan awal hingga penyetelan kinerja lanjutan untuk basis kode yang besar.

GroupDocs.Comparison untuk Java adalah pustaka yang memungkinkan perbandingan programatik dokumen dan direktori. Ia mendukung lebih dari 70 format input dan output serta dapat memproses direktori dengan hingga 10.000 file tanpa memuat seluruh set file ke memori, menjadikannya pilihan kuat untuk audit skala perusahaan.

Jawaban cepat

  • Apa pustaka utama? groupdocs comparison java
  • Versi Java yang didukung? Java 8 atau lebih tinggi
  • Waktu penyiapan tipikal? 10–15 menit untuk perbandingan dasar
  • Apakah lisensi diperlukan? Ya – diperlukan lisensi percobaan atau komersial
  • Format output? HTML (default) atau PDF

Apa itu bandingkan folder java?

Frasa “bandingkan folder java” mengacu pada penggunaan API berbasis Java untuk mendeteksi perbedaan—file yang ditambahkan, dihapus, atau dimodifikasi—antara dua pohon direktori. GroupDocs.Comparison menyediakan cara tingkat‑tinggi yang tidak tergantung pada sistem file untuk melakukan operasi ini, mengembalikan laporan HTML atau PDF terperinci yang menyoroti setiap perubahan.

Mengapa membandingkan folder java penting (lebih dari yang Anda kira)

Perbandingan direktori bukan hanya tentang menemukan file yang hilang; ia merupakan titik kontrol kritis untuk integritas data, kepatuhan regulasi, dan stabilitas rilis. Dengan mengotomatisasi proses Anda menghilangkan kesalahan manusia, mempercepat audit, dan memperoleh satu sumber kebenaran yang dapat diarsipkan untuk referensi di masa mendatang.

Manfaat yang terukur

  • Kecepatan: Memproses direktori 5.000 file dalam kurang dari 30 detik pada server 8‑core tipikal.
  • Cakupan: Mendeteksi perubahan pada lebih dari 70 tipe dokumen, dari DOCX hingga PNG.
  • Skalabilitas: Menangani file hingga 2 GB masing‑masing tanpa menghabiskan heap JVM ketika dikonfigurasi dengan mode streaming.
  • Akurasi: Melaporkan perbedaan dengan fidelitas 99,9 %, mempertahankan tata letak, tabel, dan gambar.

Prasyarat dan kebutuhan penyiapan

Sebelum kita mulai menulis kode, pastikan lingkungan Anda siap. Berikut yang Anda perlukan (dan mengapa):

Persyaratan esensial

  1. Java 8 atau lebih tinggi – GroupDocs.Comparison menggunakan fitur bahasa modern dan API terkini.
  2. Maven 3.6+ – Untuk resolusi dependensi yang handal; penanganan JAR manual rawan kesalahan.
  3. IDE dengan dukungan Java yang baik – IntelliJ IDEA atau Eclipse direkomendasikan untuk debugging dan refactoring.
  4. Setidaknya 2 GB RAM – Perbandingan direktori besar dapat mengonsumsi memori signifikan, terutama saat menghasilkan laporan HTML.

Prasyarat pengetahuan

  • Sintaks Java dasar (loop, penanganan pengecualian, try‑with‑resources).
  • Familiaritas dengan I/O file (java.nio.file.Path, API Files).
  • Memahami bagian <dependency> dan <repository> pada Maven.

Opsional namun membantu

  • Pengalaman dengan SLF4J/Logback untuk logging.
  • Pengetahuan tentang konsep multi‑threading jika Anda berencana memparalelkan perbandingan.
  • Pengetahuan dasar HTML untuk menyesuaikan laporan yang dihasilkan.

Menyiapkan GroupDocs.Comparison untuk Java

Mari integrasikan pustaka ini ke dalam proyek Anda. Penyiapan cukup sederhana, namun ada beberapa hal yang perlu diwaspadai.

Konfigurasi Maven

Tambahkan dependensi dan repositori berikut ke pom.xml Anda. Pastikan mengganti placeholder versi dengan nomor rilis terbaru dari situs resmi GroupDocs.

<dependency>
    <groupId>com.groupdocs</groupId>
    <artifactId>groupdocs-comparison</artifactId>
    <version>25.2</version>
</dependency>

<repository>
    <id>groupdocs-repo</id>
    <url>https://repo.groupdocs.com/maven2</url>
</repository>

Tip pro: Selalu verifikasi nomor versi pada halaman unduhan produk; rilis terbaru menyertakan perbaikan kinerja dan dukungan format tambahan.

Penyiapan lisensi (jangan lewatkan ini)

GroupDocs tidak gratis, tetapi mereka menawarkan beberapa opsi lisensi:

  • Percobaan gratis: Percobaan 30 hari dengan semua fitur—ideal untuk evaluasi.
  • Lisensi sementara: Percobaan diperpanjang untuk lingkungan pengembangan dan pengujian.
  • Lisensi komersial: Diperlukan untuk penyebaran produksi.

Dapatkan lisensi Anda dari:

Inisialisasi dasar dan pengujian

Setelah build Maven berhasil, buat kelas uji sederhana yang memuat lisensi dan menjalankan perbandingan minimal. Jika program berjalan tanpa melempar pengecualian, lingkungan Anda telah terkonfigurasi dengan benar.

import com.groupdocs.comparison.Comparison;
import com.groupdocs.comparison.License;

public class InitTest {
    public static void main(String[] args) throws Exception {
        License license = new License();
        license.setLicense("GroupDocs.Comparison.lic");
        // Simple sanity check
        Comparison comparison = new Comparison();
        System.out.println("GroupDocs.Comparison initialized successfully.");
    }
}

Jika ini berjalan tanpa error, Anda siap melanjutkan. Jika tidak, periksa kembali pengaturan Maven Anda dan pastikan mesin dapat mengakses server lisensi GroupDocs.

Implementasi inti: perbandingan direktori

Sekarang saatnya membandingkan direktori secara nyata — kami akan mulai dengan implementasi dasar lalu menambahkan fitur lanjutan.

Bagaimana cara membandingkan folder java?

Muat dua path direktori, konfigurasikan opsi perbandingan, dan panggil API. Dalam tiga baris saja Anda dapat menghasilkan laporan HTML lengkap yang mencantumkan setiap file yang ditambahkan, dihapus, atau dimodifikasi.

Comparison comparison = new Comparison();
comparison.compare("C:/Project/v1", "C:/Project/v2", "C:/Reports/diff.html");

Metode compare memindai kedua folder secara rekursif, mencocokkan file berdasarkan nama, dan menulis laporan HTML visual ke lokasi target. Laporan menyoroti perubahan baris‑per‑baris untuk file berbasis teks serta menampilkan pratinjau berdampingan untuk gambar dan PDF.

Kelas Comparison adalah titik masuk API utama yang melakukan perbandingan direktori dan menghasilkan laporan.

Bungkus pemanggilan dalam blok try‑with‑resources (atau gunakan metode close pada objek Comparison) untuk memastikan semua handle file dilepaskan segera, terutama saat memproses ribuan file.

Opsi konfigurasi lanjutan

Penyiapan dasar cukup untuk kebanyakan skenario, namun proyek dunia nyata sering memerlukan perilaku yang disesuaikan.

Menyesuaikan format output

GroupDocs.Comparison dapat mengekspor laporan sebagai PDF, DOCX, atau HTML biasa. Mengganti format cukup dengan mengubah ekstensi file pada pemanggilan compare.

Memfilter file dan direktori

Jika Anda hanya peduli pada tipe file tertentu (misalnya .java dan .xml), sediakan predikat filter untuk melewatkan file yang tidak relevan dan secara dramatis meningkatkan kinerja.

comparison.setFileFilter(path -> path.toString().endsWith(".java") || path.toString().endsWith(".xml"));

Masalah umum dan solusinya

Mari bahas masalah yang kemungkinan akan Anda temui (karena hukum Murphy juga berlaku untuk pemrograman).

Masalah 1: OutOfMemoryError dengan direktori besar

Jawaban langsung: Tingkatkan ukuran heap JVM (-Xmx4g atau lebih) dan aktifkan mode streaming pada opsi Comparison untuk memproses file secara berurutan alih‑alih memuat semuanya ke memori.

Saat menangani direktori berisi puluhan ribu file, pendekatan default yang memuat seluruh data ke memori dapat melampaui heap. Mode streaming membaca setiap file saat dibutuhkan, menjaga jejak memori di bawah 200 MB bahkan untuk proses 10.000 file.

Masalah 2: FileNotFoundException meskipun path sudah benar

Jawaban langsung: Pastikan proses Java memiliki izin baca untuk direktori sumber dan izin tulis untuk folder output; juga pastikan spasi atau karakter khusus dalam path telah di‑escape dengan benar.

Penyebab umum meliputi pembatasan ACL tingkat OS, share jaringan yang memerlukan autentikasi, dan karakter Unicode yang perlu penanganan eksplisit via java.nio.file.Paths.

Masalah 3: Perbandingan memakan waktu lama

Jawaban langsung: Terapkan filter file untuk mengecualikan aset biner besar, aktifkan pemrosesan multi‑thread untuk sub‑folder yang independen, dan pantau kemajuan dengan listener callback untuk mengidentifikasi bottleneck lebih awal.

Paralelisasi perbandingan sub‑direktori dapat memotong waktu eksekusi hingga 70 % pada server 8‑core, sementara callback kemajuan memungkinkan Anda menampilkan progress bar sederhana di console untuk pekerjaan yang lama.

Optimasi kinerja untuk perbandingan skala besar

Ketika Anda menangani direktori dengan ribuan file, kinerja menjadi krusial. Berikut cara mengoptimalkannya:

Praktik terbaik manajemen memori

Kelas ComparisonOptions memungkinkan Anda mengatur perilaku proses perbandingan, seperti mengaktifkan mode streaming, menetapkan batas ukuran file, dan memilih format output.

  • Aktifkan mode streaming (ComparisonOptions.setUseStreaming(true)).
  • Batasi ukuran maksimum file yang diproses (setMaxFileSize(200 * 1024 * 1024) untuk 200 MB).
  • Tutup objek Comparison secara eksplisit setelah setiap run.

Strategi pemrosesan batch

Bagi pohon direktori besar menjadi batch logis (misalnya per modul atau per rentang tanggal) dan jalankan tiap batch secara berurutan. Ini mencegah JVM pernah memuat lebih dari satu batch sekaligus di memori.

Pemrosesan paralel untuk direktori independen

Jika Anda memiliki banyak pasangan direktori untuk dibandingkan (misalnya build malam untuk beberapa micro‑service), luncurkan instance Comparison terpisah dalam thread pool. Setiap thread bekerja pada pasangannya masing‑masing, memanfaatkan semua core CPU.

Kasus penggunaan dunia nyata dan aplikasi industri

Perbandingan direktori bukan hanya alat bagi developer — ia digunakan lintas industri untuk proses bisnis kritis:

Pengembangan perangkat lunak dan DevOps

Manajemen rilis: Bandingkan folder staging vs produksi sebelum deployment untuk menangkap drift konfigurasi. Laporan HTML dapat dilampirkan pada pull‑request untuk tinjauan pemangku kepentingan.

Keuangan dan kepatuhan

Pemeliharaan jejak audit: Institusi keuangan menggunakan perbandingan direktori untuk melacak perubahan dokumen demi kepatuhan regulasi, memastikan setiap amandemen tercatat dan diarsipkan.

Manajemen data dan proses ETL

Verifikasi integritas data: Setelah migrasi data massal, jalankan perbandingan folder untuk menjamin setiap file sumber berhasil dipindahkan ke data lake target.

Manajemen konten dan penerbitan

Kontrol versi untuk tim non‑teknis: Tim pemasaran dapat membandingkan dua versi folder aset situs web tanpa perlu pengetahuan Git, menerima diff visual yang jelas.

Tips lanjutan dan praktik terbaik

Setelah bekerja dengan perbandingan direktori di lingkungan produksi, berikut beberapa pelajaran penting:

Logging dan monitoring

Integrasikan SLF4J dengan appender file bergulir untuk merekam waktu mulai, waktu selesai, jumlah file yang diproses, dan pengecualian apa pun. Log ini menjadi sangat berharga saat menyelidiki kegagalan intermiten.

Pemulihan error dan ketahanan

Bungkus pemanggilan compare dalam blok retry yang menangkap error I/O transien (misalnya gangguan jaringan pada drive yang dipasang) dan jalankan ulang perbandingan hingga tiga kali sebelum menghentikan.

Manajemen konfigurasi

Eksternalisasikan semua path, format output, dan flag kinerja ke dalam file application.yml atau properties. Ini memungkinkan tim operasi menyesuaikan pengaturan tanpa harus meng‑compile ulang JAR.

Penanganan path lintas platform

Selalu bangun path dengan java.nio.file.Paths.get(...) dan gunakan File.separator saat menggabungkan string. Ini menghindari bug saat berpindah dari Windows (\) ke Linux (/).

Mengabaikan timestamp ketika tidak relevan

Jika hanya perubahan konten yang penting, setel CompareOptions.setIgnoreMetadata(true). Ini mencegah false positive yang disebabkan oleh pembaruan timestamp otomatis pada file yang disalin.

Memecahkan masalah umum pada deployment

Berjalan di development, gagal di production

Jawaban langsung: Periksa perbedaan sensitivitas huruf (Windows vs Linux), verifikasi izin sistem file, dan ganti pemisah path yang hard‑coded dengan File.separator.

Server produksi biasanya berjalan di Linux, di mana myFile.txt dan MyFile.txt dianggap berbeda. Gunakan API Path untuk menormalkan case dan menghindari ketidaksesuaian tidak sengaja.

Hasil tidak konsisten

Jawaban langsung: Pastikan tidak ada proses eksternal yang memodifikasi file selama run perbandingan, dan konfigurasikan CompareOptions untuk mengabaikan timestamp jika menyebabkan perbedaan palsu.

Menjalankan perbandingan pada snapshot read‑only (misalnya volume snapshot yang dipasang) menjamin hasil yang deterministik.

Pertanyaan yang sering diajukan

T: Bagaimana cara menangani direktori dengan jutaan file?
J: Gabungkan pemrosesan batch, tingkatkan heap JVM (-Xmx8g atau lebih), aktifkan mode streaming, dan jalankan perbandingan sub‑direktori secara paralel. Bagian Strategi Pemrosesan Batch dan Pemrosesan Paralel menyediakan pola siap pakai.

T: Bisakah saya membandingkan direktori yang berada di server berbeda?
J: Ya, tetapi latensi jaringan mendominasi waktu eksekusi. Untuk kinerja terbaik, salin direktori remote ke lokal terlebih dahulu atau mount share remote dengan bandwidth I/O yang cukup sebelum memanggil perbandingan.

T: Format file apa saja yang didukung oleh GroupDocs.Comparison?
J: GroupDocs.Comparison mendukung lebih dari 70 format, termasuk DOC/DOCX, PDF, PPT/PPTX, XLS/XLSX, TXT, HTML, XML, CSV, serta tipe gambar umum (PNG, JPEG, BMP). Lihat dokumentasi resmi untuk daftar terbaru.

T: Bagaimana saya dapat mengintegrasikan perbandingan ini ke dalam pipeline CI/CD?
J: Paketkan logika perbandingan ke dalam JAR yang dapat dijalankan atau plugin Maven, lalu panggil sebagai langkah build di Jenkins, GitHub Actions, Azure Pipelines, atau GitLab CI. Ekspor laporan HTML sebagai artefak build untuk ditinjau selanjutnya.

T: Apakah memungkinkan menyesuaikan tampilan laporan HTML?
J: Template HTML bawaan bersifat tetap, namun Anda dapat memproses file yang dihasilkan—menyuntikkan CSS atau JavaScript khusus—untuk menyesuaikan branding perusahaan atau menambahkan elemen interaktif.


Terakhir diperbarui: 2026-08-09
Diuji dengan: GroupDocs.Comparison 25.2 (Java)
Penulis: GroupDocs

<repositories>
    <repository>
        <id>repository.groupdocs.com</id>
        <name>GroupDocs Repository</name>
        <url>https://releases.groupdocs.com/comparison/java/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>com.groupdocs</groupId>
        <artifactId>groupdocs-comparison</artifactId>
        <version>25.2</version>
    </dependency>
</dependencies>
import com.groupdocs.comparison.Comparer;

public class Main {
    public static void main(String[] args) {
        try {
            Comparer comparer = new Comparer();
            System.out.println("GroupDocs.Comparison initialized successfully!");
        } catch (Exception e) {
            System.err.println("Setup issue: " + e.getMessage());
        }
    }
}
String sourceDirectoryPath = "YOUR_DOCUMENT_DIRECTORY/source_directory";
String targetDirectoryPath = "YOUR_DOCUMENT_DIRECTORY/target_directory";
String outputFileName = "YOUR_OUTPUT_DIRECTORY/compare_result.html";
import com.groupdocs.comparison.options.CompareOptions;
import com.groupdocs.comparison.options.enums.FolderComparisonExtension;

CompareOptions compareOptions = new CompareOptions();
compareOptions.setDirectoryCompare(true);
compareOptions.setFolderComparisonExtension(FolderComparisonExtension.HTML);
try (Comparer comparer = new Comparer(sourceDirectoryPath, compareOptions)) {
    comparer.add(targetDirectoryPath, compareOptions);
    comparer.compareDirectory(outputFileName, compareOptions);
    System.out.println("Directory comparison completed. Results saved to: " + outputFileName);
} catch (Exception e) {
    System.err.println("Comparison failed: " + e.getMessage());
    e.printStackTrace();
}
CompareOptions compareOptions = new CompareOptions();
compareOptions.setDirectoryCompare(true);

// HTML for human review
compareOptions.setFolderComparisonExtension(FolderComparisonExtension.HTML);

// Or PDF for formal reports
// compareOptions.setFolderComparisonExtension(FolderComparisonExtension.PDF);
CompareOptions compareOptions = new CompareOptions();
compareOptions.setDirectoryCompare(true);

// Skip temporary files and build directories
// Note: Exact filtering syntax may vary - check current API documentation
compareOptions.setShowDeletedContent(false); // Don't highlight deleted files
compareOptions.setShowInsertedContent(true); // Do highlight new files
// JVM args: -Xmx4g -Xms2g

// For very large directories, consider processing subdirectories separately
String[] subdirectories = {"subdir1", "subdir2", "subdir3"};
for (String subdir : subdirectories) {
    String sourceSub = sourceDirectoryPath + "/" + subdir;
    String targetSub = targetDirectoryPath + "/" + subdir;
    // Process each subdirectory individually
}
// Better path handling
Path sourcePath = Paths.get(sourceDirectoryPath).toAbsolutePath();
Path targetPath = Paths.get(targetDirectoryPath).toAbsolutePath();

if (!Files.exists(sourcePath)) {
    throw new IllegalArgumentException("Source directory doesn't exist: " + sourcePath);
}
if (!Files.exists(targetPath)) {
    throw new IllegalArgumentException("Target directory doesn't exist: " + targetPath);
}
// Add progress monitoring
CompareOptions compareOptions = new CompareOptions();
compareOptions.setDirectoryCompare(true);

// Log progress (pseudo-code - actual implementation may vary)
long startTime = System.currentTimeMillis();
try (Comparer comparer = new Comparer(sourceDirectoryPath, compareOptions)) {
    comparer.add(targetDirectoryPath, compareOptions);
    comparer.compareDirectory(outputFileName, compareOptions);
    long duration = System.currentTimeMillis() - startTime;
    System.out.println("Comparison completed in: " + (duration / 1000) + " seconds");
}
// Increase heap size via JVM arguments
// -Xmx8g (for 8GB max heap)
// -XX:+UseG1GC (for better garbage collection with large heaps)

// In your code, help the GC by nulling large objects
CompareOptions compareOptions = new CompareOptions();
try (Comparer comparer = new Comparer(sourceDirectoryPath, compareOptions)) {
    // ... do comparison
    comparer.compareDirectory(outputFileName, compareOptions);
} // comparer auto‑closed here
compareOptions = null; // Help GC
public void compareDirectoriesInBatches(String sourceDir, String targetDir, int batchSize) {
    try {
        File[] sourceFiles = new File(sourceDir).listFiles();
        if (sourceFiles != null) {
            for (int i = 0; i < sourceFiles.length; i += batchSize) {
                int end = Math.min(i + batchSize, sourceFiles.length);
                processBatch(sourceFiles, i, end, targetDir);
                
                // Optional: pause between batches to prevent system overload
                Thread.sleep(1000);
            }
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new RuntimeException("Batch processing interrupted", e);
    }
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

ExecutorService executor = Executors.newFixedThreadPool(4);
List<Future<String>> futures = new ArrayList<>();

for (DirectoryPair pair : directoryPairs) {
    Future<String> future = executor.submit(() -> {
        // Perform comparison for this pair
        return compareDirectoryPair(pair.source, pair.target);
    });
    futures.add(future);
}

// Wait for all comparisons to complete
for (Future<String> future : futures) {
    try {
        String result = future.get();
        System.out.println("Comparison result: " + result);
    } catch (Exception e) {
        System.err.println("Comparison failed: " + e.getMessage());
    }
}

executor.shutdown();
// Automated pre-deployment check
String stagingConfig = "/app/staging/config";
String productionConfig = "/app/production/config";
String reportPath = "/reports/deployment-check-" + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE) + ".html";

CompareOptions options = new CompareOptions();
options.setDirectoryCompare(true);
options.setFolderComparisonExtension(FolderComparisonExtension.HTML);

try (Comparer comparer = new Comparer(stagingConfig, options)) {
    comparer.add(productionConfig, options);
    comparer.compareDirectory(reportPath, options);
    
    // Integration with deployment pipeline
    if (hasSignificantDifferences(reportPath)) {
        throw new RuntimeException("Deployment blocked: significant configuration differences detected");
    }
}
// Monthly compliance check
String previousMonthDocs = "/compliance/2024-11/documents";
String currentMonthDocs = "/compliance/2024-12/documents";
String auditReport = "/audit/compliance-changes-december-2024.html";

// Compare and generate audit‑ready reports
performComplianceComparison(previousMonthDocs, currentMonthDocs, auditReport);
public boolean verifyDataMigration(String sourceDataDir, String migratedDataDir) {
    try {
        CompareOptions options = new CompareOptions();
        options.setDirectoryCompare(true);
        
        String tempReport = "/tmp/migration-verification.html";
        try (Comparer comparer = new Comparer(sourceDataDir, options)) {
            comparer.add(migratedDataDir, options);
            comparer.compareDirectory(tempReport, options);
        }
        
        // Custom logic to parse results and determine if migration was successful
        return analyzeComparisonResults(tempReport);
    } catch (Exception e) {
        System.err.println("Migration verification failed: " + e.getMessage());
        return false;
    }
}
// Weekly content audit for marketing team
String lastWeekContent = "/content/backup/week-47";
String currentContent = "/content/current";
String marketingReport = "/reports/content-changes-week-48.html";

CompareOptions options = new CompareOptions();
options.setDirectoryCompare(true);
options.setFolderComparisonExtension(FolderComparisonExtension.HTML);

// Generate human‑readable report for non‑technical stakeholders
generateContentChangeReport(lastWeekContent, currentContent, marketingReport, options);
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

private static final Logger logger = LoggerFactory.getLogger(DirectoryComparer.class);

public void compareWithLogging(String source, String target, String output) {
    logger.info("Starting directory comparison: {} vs {}", source, target);
    long startTime = System.currentTimeMillis();
    
    try {
        CompareOptions options = new CompareOptions();
        options.setDirectoryCompare(true);
        
        try (Comparer comparer = new Comparer(source, options)) {
            comparer.add(target, options);
            comparer.compareDirectory(output, options);
        }
        
        long duration = System.currentTimeMillis() - startTime;
        logger.info("Comparison completed successfully in {}ms. Report: {}", duration, output);
        
    } catch (Exception e) {
        logger.error("Directory comparison failed for {} vs {}: {}", source, target, e.getMessage(), e);
        throw new RuntimeException("Comparison failed", e);
    }
}
public void compareWithRetry(String source, String target, String output, int maxRetries) {
    int attempts = 0;
    Exception lastException = null;
    
    while (attempts < maxRetries) {
        try {
            performComparison(source, target, output);
            return; // Success!
        } catch (Exception e) {
            lastException = e;
            attempts++;
            
            if (attempts < maxRetries) {
                try {
                    Thread.sleep(1000 * attempts); // Exponential backoff
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    throw new RuntimeException("Retry interrupted", ie);
                }
            }
        }
    }
    
    throw new RuntimeException("Comparison failed after " + maxRetries + " attempts", lastException);
}
// application.properties
comparison.output.format=HTML
comparison.max.retries=3
comparison.batch.size=100
comparison.parallel.threads=4

// In your code
@Value("${comparison.output.format:HTML}")
private String outputFormat;

@Value("${comparison.max.retries:3}")
private int maxRetries;
// Use platform-independent path handling
Path sourcePath = Paths.get(sourceDirectory);
Path targetPath = Paths.get(targetDirectory);
Path outputPath = Paths.get(outputDirectory);

// Validate permissions before starting
if (!Files.isReadable(sourcePath)) {
    throw new IllegalStateException("Cannot read source directory: " + sourcePath);
}
if (!Files.isReadable(targetPath)) {
    throw new IllegalStateException("Cannot read target directory: " + targetPath);
}
if (!Files.isWritable(outputPath.getParent())) {
    throw new IllegalStateException("Cannot write to output directory: " + outputPath.getParent());
}
CompareOptions options = new CompareOptions();
options.setDirectoryCompare(true);
// Configure to ignore timestamps and focus on content
// (exact options may vary - check API documentation)
options.setIgnoreWhitespaces(true);
options.setIgnoreFormatting(true);

Tutorial Terkait