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,其中包含两个开始和结束位置的索引.
需要一个写在outByte中的最后一个字节的索引,当你到达那个索引时你必须停止读取.
>只需读取与数据数组中相同的字节数,以避免读入不属于同一文件的缓冲区的“未知”部分.
换句话说,不要将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“缓冲区”,如果那就是你正在做的事情……我根本就没有根据你在答案中提供的内容进行跟踪.也许你可以准确地澄清什么是重复使用.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。