我使用这个简单的模式在ASP.NET应用程序中创建docx文件:
var outputFileName = "creating some file name here...";
var outputFile = string.Format("~/App_Data/files/{0}.docx", outputFileName);
// creating a file stream to write to
var outputStream = new FileStream(HttpContext.Current.Server.MapPath(outputFile), FileMode.OpenOrCreate);
// creating the default template
using (var sr = new StreamReader(HttpContext.Current.Server.MapPath("~/some-template.docx"), Encoding.UTF8)) {
var l = (int)sr.BaseStream.Length;
var buffer = new byte[l];
sr.BaseStream.Read(buffer, 0, l);
outputStream.Write(buffer, 0, l);
}
// creating the document parts
using (WordprocessingDocument docx = WordprocessingDocument.Open(outputStream, true)) {
// adding parts here...
// adding a large amount of data in an iterator
foreach(var item in someList) {
// adding some parts...
outputStream.Flush();
}
docx.Close();
}
outputStream.Flush();
outputStream.Close();
outputStream.Dispose();
我必须说,我正在处理的数据大约是来自DB的100,000条记录。
在当地,它运作得很好;在生产服务器(赢得2012 R2)中,它适用于小文件;但是在大文件中(当写入文件的记录太多时)我收到此错误:
无法创建互斥锁。 (HRESULT异常:0x80131464)
这是堆栈跟踪:
at System.IO.IsolatedStorage.IsolatedStorageFile.Open(String infoFile,String syncName) 在System.IO.IsolatedStorage.IsolatedStorageFile.Lock(布尔和锁定) 在System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(字符串路径,FileMode模式,FileAccess访问,FileShare共享,Int32 bufferSize,IsolatedStorageFile isf) 在MS.Internal.IO.Packaging.PackagingUtilities.SafeIsolatedStorageFileStream..ctor(字符串路径,FileMode模式,FileAccess访问,FileShare共享,ReliableIsolatedStorageFileFolder文件夹) 在MS.Internal.IO.Packaging.PackagingUtilities.CreateUserScopedIsolatedStorageFileStreamWithRandomName(Int32 retryCount,String& fileName) 在MS.Internal.IO.Packaging.SparseMemoryStream.SwitchModeIfNecessary() 在MS.Internal.IO.Packaging.SparseMemoryStream.Write(Byte []缓冲区,Int32偏移量,Int32计数) 在MS.Internal.IO.Packaging.CompressEmulationStream.Write(Byte []缓冲区,Int32偏移量,Int32计数) 在MS.Internal.IO.Packaging.CompressStream.Write(Byte []缓冲区,Int32偏移量,Int32计数) at MS.Internal.IO.Zip.ProgressiveCrcCalculatingStream.Write(Byte [] buffer,Int32 offset,Int32 count) 在MS.Internal.IO.Zip.ZipIOModeEnforcingStream.Write(Byte []缓冲区,Int32偏移量,Int32计数) 在System.Xml.XmlUtf8RawTextWriter.FlushBuffer() 在System.Xml.XmlUtf8RawTextWriter.RawText(Char * pSrcBegin,Char * pSrcEnd) 在System.Xml.XmlUtf8RawTextWriter.RawText(String s) at System.Xml.XmlUtf8RawTextWriter.WriteStartAttribute(String prefix,String localName,String ns) at System.Xml.XmlWellFormedWriter.WriteStartAttribute(String prefix,String localName,String namespaceName) 在DocumentFormat.OpenXml.OpenXmlElement.WriteAttributesTo(XmlWriter xmlWriter) 在DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) 在DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) 在DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) 在DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) 在DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) 在DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) 在DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) 在DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) 在DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) 在DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) 在DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) 在DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) 在DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) 在DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) 在DocumentFormat.OpenXml.OpenXmlElement.WriteTo(XmlWriter xmlWriter) 在DocumentFormat.OpenXml.OpenXmlCompositeElement.WriteContentTo(XmlWriter w) 在DocumentFormat.OpenXml.OpenXmlPartRootElement.WriteTo(XmlWriter xmlWriter) 在DocumentFormat.OpenXml.OpenXmlPartRootElement.SaveToPart(OpenXmlPart openXmlPart) 在DocumentFormat.OpenXml.OpenXmlPartRootElement.Save() 在DocumentFormat.OpenXml.Packaging.OpenXmlPackage.SavePartContents() 在DocumentFormat.OpenXml.Packaging.OpenXmlPackage.Dispose(布尔处理) 在DocumentFormat.OpenXml.Packaging.OpenXmlPackage.Dispose() 在MyClass.GetDocx()
问题是:当我将文件写入我自己的App_Data
文件夹时,为什么要转到IsolatedStorage
?我该如何防止这种情况?
答案 0 :(得分:2)
在堆栈跟踪中,您可以找到SparseMemoryStream类。引擎盖下的这个类使用Memory Stream或Isolated Storage。它取决于2个参数,称为低水位标记和高水位标记。如果内存消耗>比高水位标记然后使用隔离存储。正如您所观察到的那样,在IIS上运行服务器端应用程序时会出现问题。不幸的是,问题是这些参数的值在CompressStream类中是硬编码的。换句话说,它是设计的。
private const long _lowWaterMark = 0x19000; // we definately would like to keep everythuing under 100 KB in memory
private const long _highWaterMark = 0xA00000; // we would like to keep everything over 10 MB on disk
EPPlus库的作者有类似的problem,在我看来,解决方案是使用非Microsoft打包库。
我不知道openxml-sdk但也许可以用其他东西替换默认的Microsoft打包解决方案。