wmjordan/PDFPatcher · error · FileNotFoundException

找不到信息文件。

Error message

找不到信息文件。

What it means

DocInfoImporter constructor (the overload taking a file path) throws FileNotFoundException when the infoDocFile argument is null or empty. The string info-file path is required to load bookmark/metadata XML; an empty path is treated as a missing file rather than being silently ignored.

Source

Thrown at App/Processor/DocInfoImporter.cs:34

		readonly float _unitFactor;
		readonly PdfInfoXmlDocument _infoDoc;
		internal PdfInfoXmlDocument InfoDoc => _infoDoc;

		readonly ImporterOptions _options;
		/// <summary>
		/// 从 <see cref="XmlDocument"/> 实例创建导入器(支持无信息文件的补丁操作)。
		/// </summary>
		/// <param name="options">导入器的选项。</param>
		/// <param name="infoDoc">包含信息文件的 <see cref="XmlDocument"/>。</param>
		internal DocInfoImporter(ImporterOptions options, PdfInfoXmlDocument infoDoc) {
			_options = options;
			_unitFactor = 1;
			_infoDoc = infoDoc;
		}

		internal DocInfoImporter(ImporterOptions options, string infoDocFile) {
			if (string.IsNullOrEmpty(infoDocFile)) {
				throw new FileNotFoundException("找不到信息文件。");
			}

			var infoDoc = new PdfInfoXmlDocument();
			if (FileHelper.HasExtension(infoDocFile, Constants.FileExtensions.Txt)) {
				OutlineManager.ImportSimpleBookmarks(infoDocFile, infoDoc);
			}
			else {
				infoDoc.Load(infoDocFile);
			}

			// 设置单位转换因数
			_unitFactor = GetUnitFactor(infoDoc.DocumentElement);
			_infoDoc = infoDoc;
			_options = options;
		}

		internal DocInfoImporter(ImporterOptions importerOptions, PdfReader pdf, PatcherOptions patcherOptions, PdfInfoXmlDocument infoDoc) {
			var v = patcherOptions.ViewerPreferences;

View on GitHub (pinned to 4782bbd9ad)

Solutions

  1. Use the (options, PdfInfoXmlDocument) constructor overload when no info file is available (it supports patch operations without an info file).
  2. Validate that infoDocFile is non-null and points to an existing file before calling this constructor.
  3. If the info file is optional in your flow, branch on string.IsNullOrEmpty and pick the appropriate constructor.

Example fix

// before
var imp = new DocInfoImporter(options, infoFile); // infoFile may be null

// after
var imp = string.IsNullOrEmpty(infoFile)
  ? new DocInfoImporter(options, new PdfInfoXmlDocument())
  : new DocInfoImporter(options, infoFile);
Defensive patterns

Strategy: validation

Validate before calling

if (string.IsNullOrEmpty(infoDocFile) || !File.Exists(infoDocFile)) {
    var imp = new DocInfoImporter(options, new PdfInfoXmlDocument());
} else {
    var imp = new DocInfoImporter(options, infoDocFile);
}

Type guard

static bool HasInfoFile(string f) => !string.IsNullOrEmpty(f) && File.Exists(f);

Prevention

When it happens

Trigger: Invoking new DocInfoImporter(options, infoDocFile) with infoDocFile == null or infoDocFile == "". This happens when a caller forgets to supply the info file path, passes a variable that was never assigned, or misuses the path-based overload when the XmlDocument-based overload was intended.

Common situations: A UI/CLI flow where the user did not select an info file but the code still called the file-path constructor instead of the XmlDocument overload; a null returned from a file-picker dialog passed straight through; refactoring that swapped which constructor is called.

Related errors


AI-assisted analysis of wmjordan/PDFPatcher@4782bbd9ad (2026-08-13). Data as JSON: /api/errors/fbb987593b891500. Report an issue: GitHub.