使用Open XML SDK v2.0创建Excel电子表格时,我们的Excel输出最初成功运行了几个月.最近Excel(所有版本)开始抱怨"Excel在'zot.xlsx'中找到了不可读的内容.你想恢复这个工作簿的内容吗?".我们使用MemoryStream作为存储在Web应用程序中创建文件,然后将其作为byte []发送到HTTP响应中,MIME类型为"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet".坏文件的解压缩内容与没有错误的文件的解压缩内容相同.
position流上属性的(整个)文档说:
- 在派生类中重写时,获取或设置当前流中的位置.
- Position属性不跟踪已消耗,跳过或两者的流中的字节数.
而已.好了,我们什么也没有告诉我们相当清楚,但是我真的很想知道它其实并不代表.什么是"位置" 的?我们为什么要改变或阅读它?如果我们改变它 - 会发生什么?
在一个实际的例子中,我有一个定期写入的流,我有一个尝试从中读取的线程(理想情况下是ASAP).通过阅读许多SO问题,我将position字段重置为零以开始阅读.完成后:
也许我不理解Stream本身 - 我将它视为FIFO管道:将数据推入一端,然后将其吸收到另一端.如果它不是这样的话,那么我是否必须将数据复制到我上次读取之后(即从位置0x84开始)回到缓冲区的开头?
我已经认真地试图研究所有这些 - 但是我是.NET的新手.也许Streams有一个漫长而自豪(无证)的历史,其他人都暗中理解.但是对于一个新手来说,这就像阅读手册到你的车,并找出:
加速踏板影响送到燃油喷射器的燃油和空气量.它不会影响娱乐系统的音量,也不会影响任何轮胎的气压(如果安装).
技术上是真的,但严肃地说,我们想要知道的是,如果我们将它捣碎到地板上你会更快 ..
编辑 - 更大的图片
我有来自串行端口,套接字或文件的数据,并且有一个线程在那里等待新数据,并将其写入一个或多个流 - 都是相同的.
我可以从另一台PC的telnet会话访问其中一个流,并且一切正常.
我现在遇到的问题是在同一程序中的代码中解析数据(在另一个重复的流上).我正在将数据复制到MemoryStream,并有一个线程来坐下并解密数据,然后将其传递回UI.这个线程dataStream.BeginRead()进入它自己的缓冲区,它返回一些(?)数量的数据,但不超过count参数.在处理了我从中获得的任何内容后BeginRead,我将剩余的数据(从我的读取点的末尾到流的末尾)复制到缓冲区的开头,这样它就不会溢出.
此时,由于写入和读取都是异步的,我不知道是否可以改变位置(因为它是'光标' - 感谢Jon).即使发送消息给其他线程说,我刚读28个字节,或什么-它不会知道哪些他们是28个字节,并且将不知道如何重置它的光标/ position.我没有子类化任何流 - 我刚刚创建了一个MemoryStream,并将其传递给线程,该线程将数据复制到所需的任何流中.
这一切都感觉太复杂了,无法做到这一点 - 我只是找不到一个我可以根据需要修改的简单例子.
人们如何处理需要发送到其他任何不能立即执行的任务的长期零星数据流?
编辑:可能的解决方案
在由于答案中的信息而尝试在队列中编写Stream包装器时,我偶然发现了Stephen Toub发布的这篇文章.
他写了一篇BlockingStream,并解释说:
.NET Framework中的大多数流都不是线程安全的,这意味着多个线程无法同时安全地访问流的实例,并且大多数流保持单个位置,在该位置将发生下一次读取或写入.另一方面,BlockingStream是线程安全的,并且在某种意义上,它隐式地保持两个位置,尽管它们都没有作为数值暴露给该类型的用户.BlockingStream通过维护写入它的数据缓冲区的内部队列来工作.将数据写入流时,写入的缓冲区将排队.当从流中读取数据时,缓冲区以先进先出(FIFO)顺序出列,并且其中的数据被传递回调用者.从这个意义上说,流中有一个位置,下一次写入将发生,下一次读取将发生.
这似乎正是我所寻找的 - 所以感谢答案的人,我只从你的答案中找到了这个.
基本上用户应该能够点击一个链接并下载多个pdf文件.但Catch是我无法在服务器或任何地方创建文件.一切都必须在记忆中.
我能够创建内存流和Response.Flush()它作为PDF格式,但如何在不创建文件的情况下压缩多个内存流.
这是我的代码:
Response.ContentType = "application/zip";
// If the browser is receiving a mangled zipfile, IIS Compression may cause this problem. Some members have found that
// Response.ContentType = "application/octet-stream" has solved this. May be specific to Internet Explorer.
Response.AppendHeader("content-disposition", "attachment; filename=\"Download.zip\"");
Response.CacheControl = "Private";
Response.Cache.SetExpires(DateTime.Now.AddMinutes(3)); // or put a timestamp in the filename in the content-disposition
byte[] abyBuffer = new byte[4096];
ZipOutputStream outStream = new ZipOutputStream(Response.OutputStream);
outStream.SetLevel(3);
#region Repeat for each Memory Stream
MemoryStream fStream = CreateClassroomRoster();// This returns …Run Code Online (Sandbox Code Playgroud) 我有两个MemoryStream实例.
如何将它们合并到一个实例中?
好吧,现在我无法从一个MemoryStream复制到另一个.这是一个方法:
public static Stream ZipFiles(IEnumerable<FileToZip> filesToZip) {
ZipStorer storer = null;
MemoryStream result = null;
try {
MemoryStream memory = new MemoryStream(1024);
storer = ZipStorer.Create(memory, GetDateTimeInRuFormat());
foreach (var currentFilePath in filesToZip) {
string fileName = Path.GetFileName(currentFilePath.FullPath);
storer.AddFile(ZipStorer.Compression.Deflate, currentFilePath.FullPath, fileName,
GetDateTimeInRuFormat());
}
result = new MemoryStream((int) storer.ZipFileStream.Length);
storer.ZipFileStream.CopyTo(result); //Does not work!
//result's length will be zero
}
catch (Exception) {
}
finally {
if (storer != null)
storer.Close();
}
return result;
}
Run Code Online (Sandbox Code Playgroud) 我有以下代码:
MemoryStream resultStream = new MemoryStream();
string users = ""//Really long string goes here
BinaryFormatter bFormatter = new BinaryFormatter();
using (MemoryStream assignedUsersStream = new MemoryStream())
{
bFormatter.Serialize(assignedUsersStream, users);
assignedUsersStream.Position = 0;
using (var compressionStream =
new DeflateStream(resultStream, CompressionLevel.Optimal))
{
assignedUsersStream.CopyTo(compressionStream);
Console.WriteLine("Compressed from {0} to {1} bytes.",
assignedUsersStream.Length.ToString(),
resultStream.Length.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
事情是resultStream永远是空的!
我在这做错了什么?
我正在使用Ionic.Zip使用此方法将ZipFile提取到内存流:
private MemoryStream GetReplayZipMemoryStream()
{
MemoryStream zipMs = new MemoryStream();
using (ZipFile zip = ZipFile.Read(myFile.zip))
{
foreach (ZipEntry zipEntry in zip)
{
if (zipEntry.FileName.StartsWith("Aligning") || zipEntry.FileName.StartsWith("Sensing"))
{
zipEntry.Extract(zipMs);
}
}
}
zipMs.Seek(0, SeekOrigin.Begin);
return zipMs;
}
Run Code Online (Sandbox Code Playgroud)
一旦我完成提取,我想读取流并根据条目文件名获取一些条目.我怎样才能做到这一点?
我尝试使用下面的代码调用,但我得到的错误ZipFile.Read(ms)说:
无法将其视为ZipFile
Stream ms = GetReplayZipMemoryStream();
using (ZipFile zip = ZipFile.Read(ms))
{
ZipEntry imageEntry = zip.Entries.First(x => x.FileName.EndsWith(".png"));
using (Stream s = imageEntry.OpenReader())
{
var image = Image.FromStream(s);
pictureBox1.Image = image;
}
}
Run Code Online (Sandbox Code Playgroud)
提前感谢您的帮助!
我在我的节点服务器上使用pdfkit(https://github.com/devongovett/pdfkit),通常创建pdf文件,然后将它们上传到s3.问题是pdfkit示例将pdf文档管道传输到节点写入流,该文件将文件写入磁盘,我按照示例操作并正常工作,但我现在的要求是将pdf文档管道传输到内存流而不是保存它在磁盘上(我还是上传到s3).我已经遵循了一些节点内存流程序,但它们似乎都没有与我一起使用pdf管道,我只能将字符串写入内存流.所以我的问题是:如何将pdf套件输出传输到内存流(或类似的东西),然后将其作为上传到s3的对象读取?
var fsStream = fs.createWriteStream(outputPath + fileName);
doc.pipe(fsStream);Run Code Online (Sandbox Code Playgroud)
提前致谢.
我正在尝试尽可能快地解析二进制文件。所以这是我首先尝试做的:
using (FileStream filestream = path.OpenRead()) {
using (var d = new GZipStream(filestream, CompressionMode.Decompress)) {
using (MemoryStream m = new MemoryStream()) {
d.CopyTo(m);
m.Position = 0;
using (BinaryReaderBigEndian b = new BinaryReaderBigEndian(m)) {
while (b.BaseStream.Position != b.BaseStream.Length) {
UInt32 value = b.ReadUInt32();
} } } } }
Run Code Online (Sandbox Code Playgroud)
哪里 BinaryReaderBigEndian类,因为它实现方式是:
public static class BinaryReaderBigEndian {
public BinaryReaderBigEndian(Stream stream) : base(stream) { }
public override UInt32 ReadUInt32() {
var x = base.ReadBytes(4);
Array.Reverse(x);
return BitConverter.ToUInt32(x, 0);
} }
Run Code Online (Sandbox Code Playgroud)
然后,我尝试使用ReadOnlySpan代替 …
不确定如何说出这个问题...欢迎编辑!无论如何......这里去了.
我目前使用Crystal Reports生成Pdfs并将输出流式传输给用户.我的代码如下所示:
System.IO.MemoryStream stream = new System.IO.MemoryStream();
stream = (System.IO.MemoryStream)this.Report.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
this.Response.Clear();
this.Response.Buffer = true;
this.Response.ContentType = "application/pdf";
this.Response.BinaryWrite(stream.ToArray());
this.Response.End();
Run Code Online (Sandbox Code Playgroud)
运行此代码后,它将Pdf流式传输到浏览器,打开Acrobat Reader.效果很好!
我的问题是当用户尝试将文件保存为实际文件名时...在这种情况下,它默认为CrystalReportPage.pdf.无论如何我可以设置这个吗?如果是这样,怎么样?
任何帮助,将不胜感激.
我想在MemoryStream中打开一个XML文件(来自zip存档),并在此流中创建一个StreamReader,将其放入GridView中.
我用这个代码:
MemoryStream ms = new MemoryStream();
entry.Extract(ms);
StreamReader reader = new StreamReader(ms);
DataSet ds = new DataSet();
ds.ReadXml(reader);
dataGridView1.DataSource = GlobalDs.Tables[0];
Run Code Online (Sandbox Code Playgroud)
如果我的XML文件是用ANSI编码的,那么它可以很好地工作.但是当我加载以UTF8编码的文件时,它会失败,即使我初始化StreamReader如下:
StreamReader reader = new StreamReader(ms, System.Text.Encoding.UTF8);
Run Code Online (Sandbox Code Playgroud)
我希望有人有想法解决我的问题.