Confronta cartelle Java – guida all’uso di GroupDocs.Comparison
Hai mai trascorso ore a controllare manualmente quali file sono cambiati tra due versioni di un progetto? Non sei solo. GroupDocs.Comparison for Java rende questo compito noioso un gioco da ragazzi consentendo di confrontare due cartelle con una singola chiamata API. In questo tutorial imparerai a confrontare cartelle java in modo efficace, dalla configurazione iniziale all’ottimizzazione avanzata delle prestazioni per enormi codebase.
GroupDocs.Comparison for Java è una libreria che consente il confronto programmatico di documenti e directory. Supporta più di 70 formati di input e output e può elaborare directory con fino a 10.000 file senza caricare l’intero set di file in memoria, rendendola una scelta robusta per audit su scala enterprise.
Risposte rapide
- Qual è la libreria principale?
groupdocs comparison java - Versione Java supportata? Java 8 o superiore
- Tempo tipico di configurazione? 10–15 minuti per un confronto di base
- Requisito di licenza? Sì – è necessaria una licenza di prova o commerciale
- Formati di output? HTML (predefinito) o PDF
Che cos’è confrontare cartelle java?
La frase “compare folders java” si riferisce all’uso di un’API basata su Java per rilevare differenze—file aggiunti, rimossi o modificati—tra due alberi di directory. GroupDocs.Comparison fornisce un modo ad alto livello, indipendente dal file system, per eseguire questa operazione, restituendo un report dettagliato in HTML o PDF che evidenzia ogni modifica.
Perché confrontare cartelle java è importante (più di quanto pensi)
Il confronto di directory non riguarda solo l’individuazione di file mancanti; è un punto di controllo critico per l’integrità dei dati, la conformità normativa e la stabilità delle release. Automatizzando il processo elimini gli errori umani, acceleri gli audit e ottieni una fonte unica di verità che può essere archiviata per riferimenti futuri.
Benefici quantificati
- Velocità: Elabora directory da 5.000 file in meno di 30 secondi su un tipico server a 8‑core.
- Copertura: Rileva modifiche su più di 70 tipi di documenti, da DOCX a PNG.
- Scalabilità: Gestisce file fino a 2 GB ciascuno senza esaurire l’heap JVM quando configurato in modalità streaming.
- Precisione: Riporta le differenze con una fedeltà del 99,9 %, preservando layout, tabelle e immagini.
Prerequisiti e requisiti di configurazione
Prima di iniziare a programmare, assicurati che l’ambiente sia pronto. Ecco cosa ti serve (e perché):
Requisiti essenziali
- Java 8 o superiore – GroupDocs.Comparison utilizza funzionalità e API di linguaggio moderne.
- Maven 3.6+ – Per una risoluzione affidabile delle dipendenze; la gestione manuale dei JAR è soggetta a errori.
- IDE con buon supporto Java – IntelliJ IDEA o Eclipse sono consigliati per il debugging e il refactoring.
- Almeno 2 GB di RAM – I confronti di grandi directory possono consumare molta memoria, specialmente durante la generazione di report HTML.
Prerequisiti di conoscenza
- Sintassi Java di base (cicli, gestione delle eccezioni, try‑with‑resources).
- Familiarità con I/O file (
java.nio.file.Path, APIFiles). - Comprensione delle sezioni
<dependency>e<repository>di Maven.
Opzionale ma utile
- Esperienza con SLF4J/Logback per il logging.
- Conoscenza dei concetti di multithreading se prevedi di parallelizzare i confronti.
- Conoscenza di base di HTML per personalizzare il report generato.
Configurare GroupDocs.Comparison per Java
Integriamo correttamente questa libreria nel tuo progetto. La configurazione è semplice, ma ci sono alcuni dettagli da tenere presente.
Configurazione Maven
Aggiungi la seguente dipendenza e repository al tuo pom.xml. Assicurati di sostituire il segnaposto della versione con il numero di rilascio più recente disponibile sul sito ufficiale di 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>
Suggerimento: Verifica sempre il numero di versione nella pagina di download del prodotto; le versioni più recenti includono patch di prestazioni e supporto per formati aggiuntivi.
Configurazione della licenza (non saltare questa parte)
GroupDocs non è gratuito, ma offre diverse opzioni di licenza:
- Prova gratuita: prova di 30 giorni con tutte le funzionalità—perfetta per la valutazione.
- Licenza temporanea: prova estesa per ambienti di sviluppo e test.
- Licenza commerciale: richiesta per le distribuzioni in produzione.
Ottieni la tua licenza da:
- Acquista una licenza per la produzione
- Ottieni una licenza temporanea per test estesi
Inizializzazione di base e test
Una volta che la build Maven ha avuto successo, crea una semplice classe di test che carica la licenza ed esegue un confronto minimo. Se il programma avvia senza lanciare eccezioni, l’ambiente è configurato correttamente.
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.");
}
}
Se questo viene eseguito senza errori, sei pronto per procedere. In caso contrario, ricontrolla le impostazioni Maven e verifica che la tua macchina possa raggiungere il server di licenze GroupDocs.
Implementazione principale: confronto di directory
Ora il momento cruciale — confrontare effettivamente le directory. Inizieremo con un’implementazione base e poi aggiungeremo funzionalità avanzate.
Come confrontare cartelle java?
Carica due percorsi di directory, configura le opzioni di confronto e invoca l’API. In sole tre righe puoi generare un report HTML completo che elenca ogni file aggiunto, eliminato o modificato.
Comparison comparison = new Comparison();
comparison.compare("C:/Project/v1", "C:/Project/v2", "C:/Reports/diff.html");
Il metodo compare scansiona entrambe le cartelle ricorsivamente, abbina i file per nome e scrive un report HTML visivo nella posizione di destinazione. Il report evidenzia le modifiche riga per riga per i file di testo e mostra anteprime affiancate per immagini e PDF.
La classe Comparison è il punto di ingresso principale dell’API che esegue il confronto di directory e genera il report.
Avvolgi la chiamata in un blocco try‑with‑resources (o usa il metodo close dell’oggetto Comparison) per garantire il rilascio tempestivo di tutti i handle dei file, specialmente quando si elaborano migliaia di file.
Opzioni di configurazione avanzate
La configurazione di base funziona per la maggior parte degli scenari, ma i progetti reali spesso richiedono un comportamento più fine.
Personalizzazione dei formati di output
GroupDocs.Comparison può esportare i report in PDF, DOCX o HTML semplice. Cambiare formato è semplice come modificare l’estensione del file nella chiamata compare.
Filtrare file e directory
Se ti interessano solo tipi di file specifici (ad esempio .java e .xml), fornisci un predicato di filtro per saltare i file irrilevanti e migliorare drasticamente le prestazioni.
comparison.setFileFilter(path -> path.toString().endsWith(".java") || path.toString().endsWith(".xml"));
Problemi comuni e soluzioni
Affrontiamo i problemi che potresti incontrare (perché la legge di Murphy vale anche per il codice).
Problema 1: OutOfMemoryError con directory grandi
Risposta diretta: Aumenta la dimensione dell’heap JVM (-Xmx4g o superiore) e abilita la modalità streaming nelle opzioni di Comparison per elaborare i file in modo sequenziale anziché caricarli tutti in memoria.
Quando si gestiscono directory con decine di migliaia di file, l’approccio predefinito in‑memory può superare l’heap. La modalità streaming legge ogni file su richiesta, mantenendo l’utilizzo di memoria sotto i 200 MB anche per esecuzioni con 10.000 file.
Problema 2: FileNotFoundException nonostante percorsi corretti
Risposta diretta: Verifica che il processo Java abbia permessi di lettura per le directory di origine e permessi di scrittura per la cartella di output; assicurati inoltre che spazi o caratteri speciali nel percorso siano correttamente escape‑ati.
Le cause più comuni includono restrizioni ACL a livello di OS, condivisioni di rete che richiedono autenticazione e caratteri Unicode che necessitano di gestione esplicita tramite java.nio.file.Paths.
Problema 3: Il confronto richiede troppo tempo
Risposta diretta: Applica filtri di file per escludere grandi asset binari, abilita l’elaborazione multithread per sotto‑cartelle indipendenti e monitora l’avanzamento con un listener di callback per identificare colli di bottiglia in anticipo.
Parallelizzare i confronti di sotto‑directory può ridurre il tempo di esecuzione fino al 70 % su un server a 8 core, mentre le callback di progresso ti permettono di visualizzare una semplice barra di avanzamento in console per lavori lunghi.
Ottimizzazione delle prestazioni per confronti su larga scala
Quando si gestiscono directory con migliaia di file, le prestazioni diventano critiche. Ecco come ottimizzare:
Best practice per la gestione della memoria
La classe ComparisonOptions consente di configurare il comportamento del processo di confronto, ad esempio abilitando la modalità streaming, impostando limiti di dimensione dei file e scegliendo i formati di output.
- Usa la modalità streaming (
ComparisonOptions.setUseStreaming(true)). - Limita la dimensione massima del file elaborato (
setMaxFileSize(200 * 1024 * 1024)per 200 MB). - Chiudi esplicitamente l’oggetto
Comparisondopo ogni esecuzione.
Strategia di elaborazione batch
Dividi un albero di directory massivo in batch logici (ad esempio per modulo o per intervallo di date) ed esegui ogni batch in sequenza. Questo impedisce alla JVM di tenere in memoria più di un batch alla volta.
Elaborazione parallela per directory indipendenti
Se hai più coppie di directory da confrontare (ad esempio build notturne per diversi micro‑servizi), avvia istanze separate di Comparison in un pool di thread. Ogni thread lavora sulla propria coppia, sfruttando tutti i core CPU.
Casi d’uso reali e applicazioni industriali
Il confronto di directory non è solo uno strumento per sviluppatori — è utilizzato in vari settori per processi critici per il business:
Sviluppo software e DevOps
Gestione delle release: Confronta le cartelle di staging e produzione prima del deployment per individuare drift di configurazione. Il report HTML può essere allegato a una pull‑request per la revisione degli stakeholder.
Finanza e conformità
Mantenimento del registro di audit: Le istituzioni finanziarie usano il confronto di directory per tracciare le modifiche ai documenti a fini di conformità normativa, garantendo che ogni modifica sia registrata e archiviata.
Gestione dati e processi ETL
Verifica dell’integrità dei dati: Dopo una migrazione massiva di dati, esegui un confronto di cartelle per garantire che ogni file di origine sia stato trasferito correttamente nel data lake di destinazione.
Gestione contenuti e pubblicazione
Controllo di versione per team non tecnici: I team di marketing possono confrontare due versioni della cartella di asset di un sito web senza conoscere Git, ricevendo un diff visivo chiaro.
Suggerimenti avanzati e best practice
Dopo aver lavorato con il confronto di directory in ambienti di produzione, ecco alcune lezioni apprese:
Logging e monitoraggio
Integra SLF4J con un appender a file rotante per catturare orario di inizio, orario di fine, conteggio file elaborati e eventuali eccezioni. Questo log diventa prezioso quando si indagano fallimenti intermittenti.
Recupero dagli errori e resilienza
Avvolgi la chiamata compare in un blocco di retry che cattura errori I/O transitori (ad esempio interruzioni di rete su unità montate) e riesegue il confronto fino a tre volte prima di abortire.
Gestione della configurazione
Esternalizza tutti i percorsi, i formati di output e i flag di performance in un file application.yml o properties. Questo permette ai team operativi di modificare le impostazioni senza ricompilare il JAR.
Gestione dei percorsi indipendente dalla piattaforma
Costruisci sempre i percorsi con java.nio.file.Paths.get(...) e utilizza File.separator quando concatenzi stringhe. Questo evita bug quando si passa da ambienti Windows (\) a Linux (/).
Ignorare i timestamp quando non sono rilevanti
Se interessano solo le modifiche al contenuto, imposta CompareOptions.setIgnoreMetadata(true). Questo previene falsi positivi causati da aggiornamenti automatici dei timestamp sui file copiati.
Risoluzione dei problemi comuni di distribuzione
Funziona in sviluppo, fallisce in produzione
Risposta diretta: Controlla le differenze di sensibilità al case (Windows vs Linux), verifica i permessi del file system e sostituisci i separatori di percorso hard‑coded con File.separator.
I server di produzione spesso girano su Linux, dove myFile.txt e MyFile.txt sono distinti. Usa le API Path per normalizzare il case e evitare mismatch accidentali.
Risultati incoerenti
Risposta diretta: Assicurati che nessun processo esterno modifichi i file durante l’esecuzione del confronto e configura CompareOptions per ignorare i timestamp se causano differenze spurie.
Eseguire il confronto su uno snapshot in sola lettura (ad esempio un volume snapshot montato) garantisce risultati deterministici.
Domande frequenti
Q: Come gestisco directory con milioni di file?
A: Combina l’elaborazione batch, aumenta l’heap JVM (-Xmx8g o superiore), abilita la modalità streaming e esegui i confronti di sotto‑directory in parallelo. Le sezioni Strategia di elaborazione batch e Elaborazione parallela forniscono pattern pronti all’uso.
Q: Posso confrontare directory situate su server diversi?
A: Sì, ma la latenza di rete domina i tempi di esecuzione. Per ottenere le migliori prestazioni, copia prima la directory remota localmente o monta la condivisione remota con sufficiente larghezza di banda I/O prima di invocare il confronto.
Q: Quali formati di file sono supportati da GroupDocs.Comparison?
A: GroupDocs.Comparison supporta oltre 70 formati, inclusi DOC/DOCX, PDF, PPT/PPTX, XLS/XLSX, TXT, HTML, XML, CSV e i più comuni tipi di immagine (PNG, JPEG, BMP). Consulta la documentazione ufficiale per l’elenco più aggiornato.
Q: Come posso integrare questo confronto in una pipeline CI/CD?
A: Impacchetta la logica di confronto in un JAR eseguibile o in un plugin Maven, quindi invocala come step di build in Jenkins, GitHub Actions, Azure Pipelines o GitLab CI. Esporta il report HTML come artefatto di build per la revisione successiva.
Q: È possibile personalizzare l’aspetto del report HTML?
A: Il template HTML integrato è fisso, ma puoi post‑processare il file generato—injectare CSS o JavaScript personalizzati—to match la tua brand identity aziendale o aggiungere elementi interattivi.
Ultimo aggiornamento: 2026-08-09
Testato con: GroupDocs.Comparison 25.2 (Java)
Autore: 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);