diff --git a/src/main/download-manager.ts b/src/main/download-manager.ts index 715e423..8489a61 100644 --- a/src/main/download-manager.ts +++ b/src/main/download-manager.ts @@ -7365,10 +7365,11 @@ export class DownloadManager extends EventEmitter { } try { const stat = await fs.promises.stat(item.targetPath); - // Require file to be either ≥50% of expected size or at least 10 KB to avoid - // recovering tiny error-response files (e.g. 9-byte "Forbidden" pages). + // Require file to be essentially complete — within one allocation unit of the + // expected size. The old 50% threshold incorrectly recovered partial downloads + // (e.g. 627 MB of 1001 MB) and triggered hybrid extraction on incomplete archives. const minSize = item.totalBytes && item.totalBytes > 0 - ? Math.max(10240, Math.floor(item.totalBytes * 0.5)) + ? Math.max(10240, item.totalBytes - ALLOCATION_UNIT_SIZE) : 10240; if (stat.size >= minSize) { // Re-check: another task may have started this item during the await @@ -7376,6 +7377,14 @@ export class DownloadManager extends EventEmitter { || item.status === "validating" || item.status === "integrity_check") { continue; } + // Guard against pre-allocated sparse files from a hard crash: file has + // the full expected size but downloadedBytes is significantly behind. + if (item.downloadedBytes > 0 && item.totalBytes && item.totalBytes > 0 + && stat.size >= item.totalBytes - ALLOCATION_UNIT_SIZE + && item.downloadedBytes < item.totalBytes * 0.95) { + logger.warn(`Item-Recovery: ${item.fileName} uebersprungen – vermutlich pre-alloc (stat=${humanSize(stat.size)}, bytes=${humanSize(item.downloadedBytes)}, total=${humanSize(item.totalBytes)})`); + continue; + } logger.info(`Item-Recovery: ${item.fileName} war "${item.status}" aber Datei existiert (${humanSize(stat.size)}), setze auf completed`); item.status = "completed"; item.fullStatus = this.settings.autoExtract ? "Entpacken - Ausstehend" : `Fertig (${humanSize(stat.size)})`;