फ़ोल्डर तुलना जावा – GroupDocs.Comparison का उपयोग करके गाइड
क्या आपने कभी दो प्रोजेक्ट संस्करणों के बीच कौन सी फ़ाइलें बदल गईं, यह मैन्युअल रूप से जांचने में घंटों बिताए हैं? आप अकेले नहीं हैं। GroupDocs.Comparison for Java इस थकाऊ कार्य को आसान बना देता है, जिससे आप एक ही API कॉल से दो फ़ोल्डर की तुलना कर सकते हैं। इस ट्यूटोरियल में आप सीखेंगे कि कैसे compare folders java को प्रभावी रूप से उपयोग किया जाए, प्रारंभिक सेटअप से लेकर बड़े कोडबेस के लिए उन्नत प्रदर्शन ट्यूनिंग तक।
GroupDocs.Comparison for Java एक लाइब्रेरी है जो दस्तावेज़ों और डायरेक्टरीज़ की प्रोग्रामेटिक तुलना सक्षम करती है। यह 70+ इनपुट और आउटपुट फ़ॉर्मैट्स को सपोर्ट करती है और पूरी फ़ाइल सेट को मेमोरी में लोड किए बिना 10,000 फ़ाइलों तक की डायरेक्टरीज़ को प्रोसेस कर सकती है, जिससे यह एंटरप्राइज़‑स्केल ऑडिट्स के लिए एक मजबूत विकल्प बनता है।
त्वरित उत्तर
- मुख्य लाइब्रेरी क्या है?
groupdocs comparison java - समर्थित Java संस्करण? Java 8 या उससे ऊपर
- आम सेटअप समय? बेसिक तुलना के लिए 10–15 मिनट
- लाइसेंस आवश्यकता? हाँ – ट्रायल या कमर्शियल लाइसेंस आवश्यक है
- आउटपुट फ़ॉर्मैट्स? HTML (डिफ़ॉल्ट) या PDF
compare folders java क्या है?
वाक्यांश “compare folders java” का अर्थ है Java‑आधारित API का उपयोग करके दो डायरेक्टरी ट्रीज़ के बीच अंतर (जोड़ी गई, हटाई गई या संशोधित फ़ाइलें) का पता लगाना। GroupDocs.Comparison इस ऑपरेशन को करने का एक हाई‑लेवल, फ़ाइल‑सिस्टम‑अज्ञेय तरीका प्रदान करता है, जो हर बदलाव को हाइलाइट करने वाली विस्तृत HTML या PDF रिपोर्ट लौटाता है।
compare folders java क्यों महत्वपूर्ण है (आपको पता नहीं था इतना)
डायरेक्टरी तुलना केवल गायब फ़ाइलों को खोजने तक सीमित नहीं है; यह डेटा इंटेग्रिटी, रेगुलेटरी कंप्लायंस और रिलीज़ स्थिरता के लिए एक महत्वपूर्ण नियंत्रण बिंदु है। प्रक्रिया को ऑटोमेट करके आप मानव त्रुटियों को समाप्त करते हैं, ऑडिट्स को तेज़ बनाते हैं और एक सिंगल सोर्स ऑफ़ ट्रुथ प्राप्त करते हैं जिसे भविष्य के संदर्भ के लिए आर्काइव किया जा सकता है।
मात्रात्मक लाभ
- गति: सामान्य 8‑कोर सर्वर पर 5,000‑फ़ाइल डायरेक्टरी को 30 सेकंड से कम में प्रोसेस करता है।
- कवरेज: DOCX से PNG तक 70+ डॉक्यूमेंट टाइप्स में बदलाव का पता लगाता है।
- स्केलेबिलिटी: प्रत्येक फ़ाइल 2 GB तक हो सकती है और स्ट्रीमिंग मोड के साथ JVM हीप को ख़त्म किए बिना प्रोसेस करता है।
- सटीकता: 99.9 % फ़िडेलिटी के साथ अंतर रिपोर्ट करता है, लेआउट, टेबल और इमेज को संरक्षित रखता है।
पूर्वापेक्षाएँ और सेटअप आवश्यकताएँ
कोडिंग शुरू करने से पहले सुनिश्चित करें कि आपका वातावरण तैयार है। आपको क्या चाहिए (और क्यों):
आवश्यक आवश्यकताएँ
- Java 8 या उससे ऊपर – GroupDocs.Comparison आधुनिक भाषा फीचर्स और API का उपयोग करता है।
- Maven 3.6+ – विश्वसनीय डिपेंडेंसी रिज़ॉल्यूशन के लिए; मैन्युअल JAR हैंडलिंग त्रुटिप्रवण है।
- अच्छे Java सपोर्ट वाला IDE – IntelliJ IDEA या Eclipse डिबगिंग और रीफ़ैक्टरिंग के लिए अनुशंसित हैं।
- कम से कम 2 GB RAM – बड़े डायरेक्टरी तुलना में मेमोरी की काफी खपत हो सकती है, विशेषकर HTML रिपोर्ट जनरेट करते समय।
ज्ञान पूर्वापेक्षाएँ
- बेसिक Java सिंटैक्स (लूप, एक्सेप्शन हैंडलिंग, try‑with‑resources)।
- फ़ाइल I/O से परिचित (
java.nio.file.Path,FilesAPI)। - Maven के
<dependency>और<repository>सेक्शन की समझ।
वैकल्पिक लेकिन उपयोगी
- लॉगिंग के लिए SLF4J/Logback का अनुभव।
- यदि आप तुलना को पैरललाइज़ करने की योजना बना रहे हैं तो मल्टी‑थ्रेडिंग कॉन्सेप्ट्स का ज्ञान।
- जनरेटेड रिपोर्ट को कस्टमाइज़ करने के लिए बेसिक HTML ज्ञान।
GroupDocs.Comparison for Java सेटअप करना
आइए इस लाइब्रेरी को आपके प्रोजेक्ट में सही तरीके से इंटीग्रेट करें। सेटअप सीधा है, लेकिन कुछ गड़बड़ियों से बचना ज़रूरी है।
Maven कॉन्फ़िगरेशन
अपनी pom.xml में निम्नलिखित डिपेंडेंसी और रिपॉज़िटरी जोड़ें। संस्करण प्लेसहोल्डर को आधिकारिक 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>
प्रो टिप: हमेशा प्रोडक्ट डाउनलोड पेज पर संस्करण नंबर की जाँच करें; नए रिलीज़ में परफ़ॉर्मेंस पैच और अतिरिक्त फ़ॉर्मैट सपोर्ट शामिल होते हैं।
लाइसेंस सेटअप (इसे न छोड़ें)
GroupDocs मुफ्त नहीं है, लेकिन वे कई लाइसेंस विकल्प प्रदान करते हैं:
- फ़्री ट्रायल: पूर्ण फीचर सेट के साथ 30‑दिन का ट्रायल—मूल्यांकन के लिए परफ़ेक्ट।
- टेम्पररी लाइसेंस: विकास और टेस्टिंग वातावरण के लिए विस्तारित ट्रायल।
- कमर्शियल लाइसेंस: प्रोडक्शन डिप्लॉयमेंट के लिए आवश्यक।
लाइसेंस प्राप्त करें:
- लाइसेंस खरीदें प्रोडक्शन के लिए
- टेम्पररी लाइसेंस प्राप्त करें विस्तारित टेस्टिंग के लिए
बेसिक इनिशियलाइज़ेशन और टेस्टिंग
एक बार आपका Maven बिल्ड सफल हो जाए, एक सरल टेस्ट क्लास बनाएं जो लाइसेंस लोड करे और न्यूनतम तुलना चलाए। यदि प्रोग्राम बिना एक्सेप्शन फेंके शुरू हो जाता है, तो आपका वातावरण सही ढंग से कॉन्फ़िगर हो गया है।
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.");
}
}
यदि यह बिना त्रुटियों के चलता है, तो आप आगे बढ़ने के लिए तैयार हैं। यदि नहीं, तो अपने Maven सेटिंग्स को दोबारा जाँचें और सुनिश्चित करें कि आपका मशीन GroupDocs लाइसेंसिंग सर्वर तक पहुँच सकता है।
कोर इम्प्लीमेंटेशन: डायरेक्टरी तुलना
अब मुख्य भाग — वास्तव में डायरेक्टरीज़ की तुलना। हम बेसिक इम्प्लीमेंटेशन से शुरू करेंगे और फिर एडवांस्ड फीचर्स जोड़ेंगे।
compare folders java कैसे करें?
दो डायरेक्टरी पाथ लोड करें, तुलना विकल्प कॉन्फ़िगर करें, और API को कॉल करें। केवल तीन लाइनों में आप एक पूर्ण HTML डिफ़ रिपोर्ट जनरेट कर सकते हैं जो हर जोड़ी गई, हटाई गई या संशोधित फ़ाइल को सूचीबद्ध करता है।
Comparison comparison = new Comparison();
comparison.compare("C:/Project/v1", "C:/Project/v2", "C:/Reports/diff.html");
compare मेथड दोनों फ़ोल्डर को रीकर्सिवली स्कैन करता है, फ़ाइलों को नाम से मिलाता है, और टार्गेट लोकेशन पर एक विज़ुअल HTML रिपोर्ट लिखता है। रिपोर्ट टेक्स्ट‑बेस्ड फ़ाइलों के लिए लाइन‑बाय‑लाइन बदलाव दिखाती है और इमेज तथा PDF के लिए साइड‑बाय‑साइड प्रीव्यू प्रदान करती है।
Comparison क्लास मुख्य API एंट्री पॉइंट है जो डायरेक्टरी तुलना करता है और रिपोर्ट जनरेट करता है।
फ़ाइल हैंडल्स को तुरंत रिलीज़ करने के लिए कॉल को try‑with‑resources ब्लॉक में रैप करें (या Comparison ऑब्जेक्ट के close मेथड का उपयोग करें), विशेषकर जब हजारों फ़ाइलों को प्रोसेस किया जा रहा हो।
एडवांस्ड कॉन्फ़िगरेशन विकल्प
बेसिक सेटअप अधिकांश परिदृश्यों के लिए काम करता है, लेकिन वास्तविक प्रोजेक्ट्स अक्सर फाइन‑ट्यून्ड बिहेवियर की मांग करते हैं।
आउटपुट फ़ॉर्मैट्स को कस्टमाइज़ करना
GroupDocs.Comparison रिपोर्ट को PDF, DOCX, या साधारण HTML के रूप में एक्सपोर्ट कर सकता है। फ़ॉर्मैट बदलना इतना सरल है कि compare कॉल में फ़ाइल एक्सटेंशन बदल दें।
फ़ाइलों और डायरेक्टरीज़ को फ़िल्टर करना
यदि आप केवल विशिष्ट फ़ाइल टाइप्स (जैसे .java और .xml) में रुचि रखते हैं, तो एक फ़िल्टर प्रेडिकेट प्रदान करें ताकि अनावश्यक फ़ाइलों को स्किप किया जा सके और प्रदर्शन में नाटकीय सुधार हो।
comparison.setFileFilter(path -> path.toString().endsWith(".java") || path.toString().endsWith(".xml"));
सामान्य समस्याएँ और समाधान
आइए उन समस्याओं को देखें जो आप संभवतः सामना करेंगे (क्योंकि मर्फ़ी का नियम कोडिंग पर भी लागू होता है)।
समस्या 1: बड़े डायरेक्टरीज़ के साथ OutOfMemoryError
सीधा उत्तर: JVM हीप साइज बढ़ाएँ (-Xmx4g या उससे अधिक) और Comparison विकल्पों में स्ट्रीमिंग मोड सक्षम करें ताकि फ़ाइलें मेमोरी में लोड करने के बजाय क्रमिक रूप से प्रोसेस हों।
जब डायरेक्टरी में दसियों हज़ार फ़ाइलें होती हैं, तो डिफ़ॉल्ट इन‑मेमोरी अप्रोच हीप को ओवरफ़्लो कर सकती है। स्ट्रीमिंग मोड प्रत्येक फ़ाइल को ऑन‑डिमांड पढ़ता है, जिससे मेमोरी फुटप्रिंट 200 MB से नीचे रहता है, यहाँ तक कि 10,000‑फ़ाइल रन के लिए भी।
समस्या 2: सही पाथ होने के बावजूद FileNotFoundException
सीधा उत्तर: सुनिश्चित करें कि Java प्रोसेस को स्रोत डायरेक्टरीज़ के लिए रीड परमिशन और आउटपुट फ़ोल्डर के लिए राइट परमिशन है; साथ ही पाथ में किसी भी स्पेस या स्पेशल कैरेक्टर को सही तरीके से एस्केप करें।
आम कारणों में OS‑लेवल ACL प्रतिबंध, नेटवर्क शेयर जो ऑथेंटिकेशन मांगते हैं, और Unicode कैरेक्टर शामिल हैं जिन्हें java.nio.file.Paths के माध्यम से स्पष्ट रूप से हैंडल करना पड़ता है।
समस्या 3: तुलना बहुत समय ले रही है
सीधा उत्तर: बड़े बाइनरी एसेट्स को एक्सक्लूड करने के लिए फ़ाइल फ़िल्टर लागू करें, स्वतंत्र सब‑फ़ोल्डर्स के लिए मल्टी‑थ्रेडेड प्रोसेसिंग सक्षम करें, और प्रोग्रेस को मॉनिटर करने के लिए कॉलबैक लिस्नर का उपयोग करें ताकि बॉटलनेक जल्दी पहचान सकें।
सब‑डायरेक्टरी तुलना को पैरललाइज़ करने से 8‑कोर सर्वर पर रनटाइम 70 % तक घट सकता है, जबकि प्रोग्रेस कॉलबैक आपको लंबी चलने वाली जॉब्स के लिए एक साधारण कंसोल प्रोग्रेस बार दिखाने में मदद करता है।
बड़े‑पैमाने की तुलना के लिए प्रदर्शन अनुकूलन
जब आप हजारों फ़ाइलों वाली डायरेक्टरीज़ से निपट रहे हों, तो प्रदर्शन अत्यंत महत्वपूर्ण हो जाता है। यहाँ ऑप्टिमाइज़ करने के तरीके हैं:
मेमोरी मैनेजमेंट बेस्ट प्रैक्टिसेज
ComparisonOptions क्लास आपको तुलना प्रक्रिया के व्यवहार को कॉन्फ़िगर करने देती है, जैसे स्ट्रीमिंग मोड सक्षम करना, फ़ाइल साइज लिमिट सेट करना, और आउटपुट फ़ॉर्मैट चुनना।
- स्ट्रीमिंग मोड उपयोग करें (
ComparisonOptions.setUseStreaming(true))। - प्रोसेस की जाने वाली अधिकतम फ़ाइल साइज सीमित करें (
setMaxFileSize(200 * 1024 * 1024)200 MB के लिए)। - प्रत्येक रन के बाद
Comparisonऑब्जेक्ट को स्पष्ट रूप से बंद करें।
बैच प्रोसेसिंग स्ट्रैटेजी
एक बड़े डायरेक्टरी ट्री को लॉजिकल बैचों में विभाजित करें (जैसे मॉड्यूल या डेट रेंज के अनुसार) और प्रत्येक बैच को क्रमिक रूप से चलाएँ। इससे JVM कभी भी एक से अधिक बैच मेमोरी में नहीं रखेगा।
स्वतंत्र डायरेक्टरीज़ के लिए पैरलल प्रोसेसिंग
यदि आपके पास कई डायरेक्टरी पेयर तुलना करने हैं (जैसे कई माइक्रो‑सर्विसेज के नाइटली बिल्ड), तो एक थ्रेड पूल में अलग‑अलग Comparison इंस्टेंस लॉन्च करें। प्रत्येक थ्रेड अपना पेयर प्रोसेस करेगा, सभी CPU कोर का उपयोग करेगा।
वास्तविक‑दुनिया उपयोग केस और उद्योग अनुप्रयोग
डायरेक्टरी तुलना केवल डेवलपर टूल नहीं है — यह विभिन्न उद्योगों में बिज़नेस‑क्रिटिकल प्रोसेस के लिए उपयोग होती है:
सॉफ़्टवेयर डेवलपमेंट और DevOps
रिलीज़ मैनेजमेंट: डिप्लॉयमेंट से पहले स्टेजिंग बनाम प्रोडक्शन फ़ोल्डर की तुलना करके कॉन्फ़िगरेशन ड्रिफ्ट पकड़ें। HTML रिपोर्ट को पुल‑रिक्वेस्ट में अटैच किया जा सकता है ताकि स्टेकहोल्डर्स रिव्यू कर सकें।
फाइनेंस और कंप्लायंस
ऑडिट ट्रेल मेन्टेनेन्स: वित्तीय संस्थान रेगुलेटरी कंप्लायंस के लिए डायरेक्टरी तुलना का उपयोग करके दस्तावेज़ बदलावों को ट्रैक करते हैं, यह सुनिश्चित करते हुए कि हर संशोधन लॉग और आर्काइव हो।
डेटा मैनेजमेंट और ETL प्रोसेसेस
डेटा इंटेग्रिटी वेरिफिकेशन: बड़े डेटा माइग्रेशन के बाद, फ़ोल्डर तुलना चलाएँ ताकि हर स्रोत फ़ाइल सही ढंग से टार्गेट डेटा लेक में लैंड हुई हो।
कंटेंट मैनेजमेंट और पब्लिशिंग
नॉन‑टेक्निकल टीमों के लिए वर्ज़न कंट्रोल: मार्केटिंग टीमें Git ज्ञान के बिना वेबसाइट के एसेट फ़ोल्डर के दो वर्ज़न की तुलना कर सकती हैं, और स्पष्ट विज़ुअल डिफ़ प्राप्त कर सकती हैं।
एडवांस्ड टिप्स और बेस्ट प्रैक्टिसेज
प्रोडक्शन में डायरेक्टरी तुलना के साथ काम करने के बाद यहाँ कुछ कठोर सीखें हैं:
लॉगिंग और मॉनिटरिंग
SLF4J को रोलिंग फ़ाइल अपेंडर के साथ इंटीग्रेट करें ताकि स्टार्ट‑टाइम, एंड‑टाइम, प्रोसेस्ड फ़ाइल काउंट, और किसी भी एक्सेप्शन को कैप्चर किया जा सके। यह लॉग इंटरमिटेंट फ़ेल्योर की जाँच में अमूल्य साबित होता है।
एरर रिकवरी और रेज़िलिएंस
compare कॉल को एक रिट्राई ब्लॉक में रैप करें जो ट्रांज़िएंट I/O एरर (जैसे माउंटेड ड्राइव पर नेटवर्क हिच) को कैच करे और तुलना को अधिकतम तीन बार री‑एक्ज़ीक्यूट करे, फिर एबॉर्ट करे।
कॉन्फ़िगरेशन मैनेजमेंट
सभी पाथ, आउटपुट फ़ॉर्मैट, और परफ़ॉर्मेंस फ्लैग्स को application.yml या properties फ़ाइल में एक्सटर्नलाइज़ करें। इससे ऑप्स टीम बिना JAR री‑कम्पाइल किए सेटिंग्स को ट्यून कर सकती है।
प्लेटफ़ॉर्म‑इंडिपेंडेंट पाथ हैंडलिंग
हमेशा java.nio.file.Paths.get(...) के साथ पाथ बनाएं और स्ट्रिंग कॉनकैटनेशन में File.separator का उपयोग करें। इससे Windows (\) से Linux (/) में माइग्रेट करते समय बग्स से बचा जा सकता है।
टाइमस्टैम्प को इग्नोर करना जब वह मायने नहीं रखता
यदि केवल कंटेंट बदलाव मायने रखते हैं, तो CompareOptions.setIgnoreMetadata(true) सेट करें। इससे कॉपी की गई फ़ाइलों पर स्वचालित टाइमस्टैम्प अपडेट के कारण फॉल्स पॉज़िटिव्स नहीं आएंगे।
सामान्य डिप्लॉयमेंट मुद्दों का ट्रबलशूटिंग
डेवलपमेंट में काम करता है, प्रोडक्शन में फेल
सीधा उत्तर: केस‑सेंसिटिविटी अंतर (Windows बनाम Linux) की जाँच करें, फ़ाइल‑सिस्टम परमिशन वेरिफ़ाई करें, और हार्ड‑कोडेड पाथ सेपरेटर को File.separator से बदलें।
प्रोडक्शन सर्वर अक्सर Linux पर चलते हैं, जहाँ myFile.txt और MyFile.txt अलग माने जाते हैं। केस को नॉर्मलाइज़ करने और मismatch से बचने के लिए Path API का उपयोग करें।
असंगत परिणाम
सीधा उत्तर: सुनिश्चित करें कि तुलना रन के दौरान कोई बाहरी प्रोसेस फ़ाइलों को मॉडिफ़ाई नहीं कर रहा है, और यदि टाइमस्टैम्प स्पुरियस डिफ़ बनाते हैं तो CompareOptions को टाइमस्टैम्प इग्नोर करने के लिए कॉन्फ़िगर करें।
रिड‑ओनली स्नैपशॉट (जैसे माउंटेड वॉल्यूम स्नैपशॉट) में तुलना चलाने से डिटरमिनिस्टिक परिणाम मिलते हैं।
अक्सर पूछे जाने वाले प्रश्न
प्रश्न: लाखों फ़ाइलों वाली डायरेक्टरीज़ को कैसे हैंडल करें?
उत्तर: बैच प्रोसेसिंग को कॉम्बाइन करें, JVM हीप बढ़ाएँ (-Xmx8g या उससे अधिक), स्ट्रीमिंग मोड सक्षम करें, और सब‑डायरेक्टरी तुलना को पैरललाइज़ करें। बैच प्रोसेसिंग स्ट्रैटेजी और पैरलल प्रोसेसिंग सेक्शन में तैयार‑टू‑यूज़ पैटर्न उपलब्ध हैं।
प्रश्न: क्या मैं विभिन्न सर्वरों पर स्थित डायरेक्टरीज़ की तुलना कर सकता हूँ?
उत्तर: हाँ, लेकिन नेटवर्क लेटेंसी रनटाइम को प्रमुख रूप से प्रभावित करती है। सर्वोत्तम परफ़ॉर्मेंस के लिए रिमोट डायरेक्टरी को पहले लोकली कॉपी करें या पर्याप्त I/O बैंडविड्थ के साथ रिमोट शेयर को माउंट करें, फिर तुलना invoke करें।
प्रश्न: GroupDocs.Comparison कौन‑से फ़ाइल फ़ॉर्मैट सपोर्ट करता है?
उत्तर: GroupDocs.Comparison 70+ फ़ॉर्मैट सपोर्ट करता है, जिसमें DOC/DOCX, PDF, PPT/PPTX, XLS/XLSX, TXT, HTML, XML, CSV, और सामान्य इमेज टाइप्स (PNG, JPEG, BMP) शामिल हैं। नवीनतम सूची के लिए आधिकारिक डॉक्यूमेंटेशन देखें।
प्रश्न: इस तुलना को CI/CD पाइपलाइन में कैसे इंटीग्रेट करें?
उत्तर: तुलना लॉजिक को एक runnable JAR या Maven प्लगइन में पैकेज करें, फिर इसे Jenkins, GitHub Actions, Azure Pipelines, या GitLab CI में बिल्ड स्टेप के रूप में invoke करें। HTML रिपोर्ट को बिल्ड आर्टिफैक्ट के रूप में एक्सपोर्ट करें ताकि डाउनस्ट्रीम रिव्यू के लिए उपलब्ध हो।
प्रश्न: क्या HTML रिपोर्ट की लुक‑एंड‑फील को कस्टमाइज़ किया जा सकता है?
उत्तर: बिल्ट‑इन HTML टेम्पलेट फिक्स्ड है, लेकिन आप जनरेटेड फ़ाइल को पोस्ट‑प्रोसेस करके कस्टम CSS या JavaScript इन्जेक्ट कर सकते हैं, जिससे आप कॉर्पोरेट ब्रांडिंग या इंटरैक्टिव एलिमेंट्स जोड़ सकते हैं।
अंतिम अपडेट: 2026-08-09
टेस्टेड विद: GroupDocs.Comparison 25.2 (Java)
लेखक: 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);