gpt4 book ai didi

c# - 小pdf文件变成巨大的字节数组

转载 作者:行者123 更新时间:2023-12-04 08:51:19 27 4
gpt4 key购买 nike

我目前正在开发一个将文本文件转换为 PDF 文件或相反的小应用程序。但是,我希望能够将转换后的文件保存在内存中,直到用户按下按钮将文件(或一组文件保存到 .zip 中)为止,所有转换后的文件都保存在字典中,并以旧路径为键和字节数组作为值。
一切正常,除非出于测试目的,我使用了一个包含 12000 多行的大文本文件并试图在文本和 PDF 之间来回切换,现在我遇到了一个奇怪的问题。
当使用这个大文件从文本到 PDF 时,一切都很好。
但是,从该文件的 PDF 格式转换为文本会在堆中占用大量内存。最终超过 2 GB 导致内存不足异常。
我应该注意到我使用的是 Itext 7。
这是我正在使用的代码:
文本转PDF

        public override byte[] ConvertFile(Stream stream, string path)
{
OnFileStartConverting(path);
string ext = Path.GetExtension(path);
TextFileType current = TextFileType.Parse(ext);
MemoryStream resultStream = new MemoryStream();

if (current.Extension.Equals(TextFileType.Txt.Extension))
{
resultStream = TextToPdf(stream, path);
}
else if (current.Extension.Equals(TextFileType.Word.Extension))
{
throw new NotImplementedException();
}

OnFileConverted(path);
return resultStream.ToArray();
}

private MemoryStream TextToPdf(Stream stream, string path)
{
MemoryStream resultStream = new MemoryStream();
StreamReader streamReader = new StreamReader(stream);
int lineCount = GetNumberOfLines(streamReader);
PdfWriter writer = new PdfWriter(resultStream);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);

int lineNumber = 1;
while (!streamReader.EndOfStream)
{
string line = streamReader.ReadLine();
Paragraph paragraph = new Paragraph(line);
document.Add(paragraph);
int percent = lineNumber * 100 / lineCount;
OnFileConverting(path, percent, lineNumber);
lineNumber++;
}

document.Close();
return resultStream;
}
PDF转文本
        public override byte[] ConvertFile(Stream stream, string path)
{
OnFileStartConverting(path);

string ext = Path.GetExtension(path);
TextFileType current = TextFileType.Parse(ext);
MemoryStream resultStream = new MemoryStream();

if (current.Extension.Equals(TextFileType.Pdf.Extension))
{
resultStream = PdfToText(stream, path);
}
else if (current.Extension.Equals(TextFileType.Word.Extension))
{
throw new NotImplementedException();
}

resultStream.Seek(0, SeekOrigin.Begin);
OnFileConverted(path);

return resultStream.ToArray();
}

private MemoryStream PdfToText(Stream stream, string path)
{
MemoryStream resultStream = new MemoryStream();
StreamWriter writer = new StreamWriter(resultStream);

PdfReader reader = new PdfReader(stream);
PdfDocument pdf = new PdfDocument(reader);
FilteredEventListener listener = new FilteredEventListener();
LocationTextExtractionStrategy extractionStrategy =
listener.AttachEventListener(new LocationTextExtractionStrategy());
PdfCanvasProcessor parser = new PdfCanvasProcessor(listener);
int numberOfPages = pdf.GetNumberOfPages();

for (int i = 1; i <= numberOfPages; i++)
{
parser.ProcessPageContent(pdf.GetPage(i));
writer.WriteLine(extractionStrategy.GetResultantText());
int percent = i * 100 / numberOfPages;
OnFileConverting(path, percent, i);
}

pdf.Close();
writer.Flush();

return resultStream;
}
从 PDF 转为文本时的内存使用情况
enter image description here
PDF 文件本身甚至不是 1000 KB(882 KB),但这对我来说很奇怪。我错过了什么吗?更奇怪的是,当我尝试使用转换后的文件本身时,它不会导致任何内存问题。

最佳答案

问题的原因在 PdfToText对于具有多页的文档,它提取的文本比那里多。LocationTextExtractionStrategy当您开始向其提供新页面时,不会忘记其内容。它不是为跨页面重复使用而设计的,您需要为每个页面创建一个新实例。
在代码中的循环中重用会导致

  • i=1要写入的第 1 页的内容 writer ;
  • i=2要写入的第 1 页和第 2 页的内容 writer ;
  • i=3要写入 writer 的第 1、2 和 3 页的内容;
  • ...

  • 因此,不要跨页面重复使用文本提取策略。而是移动您的 FilteredEventListener 的实例化, LocationTextExtractionStrategy , 和 PdfCanvasProcessor进入循环,为每个页面重新创建它们。

    关于c# - 小pdf文件变成巨大的字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64087622/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com