c# – 将byte []数组的一部分复制到PDFReader中
这是继续努力减少我的记忆负荷
How do you refill a byte array using SqlDataReader? 所以我有一个设置大小的字节数组,对于这个例子,我会说新字节[400000].在这个数组中,我将放置不同大小的pdf(小于400000). 伪代码将是: public void Run() { byte[] fileRetrievedFromDatabase = new byte[400000]; foreach (var document in documentArray) { // Refill the file with data from the database var currentDocumentSize = PopulateFileWithPDFDataFromDatabase(fileRetrievedFromDatabase); var reader = new iTextSharp.text.pdf.PdfReader(fileRetrievedFromDatabase.Take((int)currentDocumentSize ).ToArray()); pageCount = reader.NumberOfPages; // DO ADDITIONAL WORK } } private int PopulateFileWithPDFDataFromDatabase(byte[] fileRetrievedFromDatabase) { // DataAccessCode Goes here int documentSize = 0; int bufferSize = 100; // Size of the BLOB buffer. byte[] outbyte = new byte[bufferSize]; // The BLOB byte[] buffer to be filled by GetBytes. myReader = logoCMD.ExecuteReader(CommandBehavior.SequentialAccess); Array.Clear(fileRetrievedFromDatabase,fileRetrievedFromDatabase.Length); if (myReader == null) { return; } while (myReader.Read()) { documentSize = myReader.GetBytes(0,null,0); // Reset the starting byte for the new BLOB. startIndex = 0; // Read the bytes into outbyte[] and retain the number of bytes returned. retval = myReader.GetBytes(0,startIndex,outbyte,bufferSize); // Continue reading and writing while there are bytes beyond the size of the buffer. while (retval == bufferSize) { Array.Copy(outbyte,fileRetrievedFromDatabase,retval); // Reposition the start index to the end of the last buffer and fill the buffer. startIndex += retval; retval = myReader.GetBytes(0,bufferSize); } } return documentSize; } 以上代码的问题是,当我尝试访问PDF阅读器时,我一直收到“未找到重建预告片.原始错误:未找到PDF startxref”错误.我相信这是因为字节数组太长并且尾随0.但由于我正在使用字节数组,所以我不会在LOH上不断构建新对象,我需要这样做. 那么我如何获得我需要的数组并将其发送到PDFReader呢? 更新 所以我查看了源代码,发现我的实际代码中有一些变量令人困惑.我基本上在循环的每次迭代中重用fileRetrievedFromDatabase对象.由于它通过引用传递,它被清除(设置为全零),然后填充PopulateFileWithPDFDataFromDatabase.然后,此对象用于创建新PDF. 如果我没有这样做,将在每次迭代中创建一个新的大字节数组,并且Large Object Heap会变满并最终抛出OutOfMemory异常. 解决方法
您至少有两个选择:
>将您的缓冲区视为circular buffer,其中包含两个开始和结束位置的索引. 换句话说,不要将bufferSize作为最后一个参数,而是使用data.Length. // Read the bytes into outbyte[] and retain the number of bytes returned. retval = myReader.GetBytes(0,data.Length); 如果数据长度为10且你的outbyte缓冲区为15,那么你应该只读取data.Length而不是bufferSize. 但是,我仍然没有看到你如何重复使用outbyte“缓冲区”,如果那就是你正在做的事情……我根本就没有根据你在答案中提供的内容进行跟踪.也许你可以准确地澄清什么是重复使用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |