我试图将字符串写入内存流,但失败并显示错误消息:
Memory stream is not expandable.
Run Code Online (Sandbox Code Playgroud)
产生此问题的代码行:
context.Response.Filter = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(myPage));
Run Code Online (Sandbox Code Playgroud)
有人有解决方法/解决方法吗?
堆栈跟踪:
[NotSupportedException: Memory stream is not expandable.]
System.IO.MemoryStream.set_Capacity(Int32 value) +9385744
System.IO.MemoryStream.EnsureCapacity(Int32 value) +50
System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) +265
System.Web.HttpWriter.FilterIntegrated(Boolean finalFiltering, IIS7WorkerRequest wr) +9155697
System.Web.HttpResponse.FilterOutput() +159
System.Web.CallFilterExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +52
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
Run Code Online (Sandbox Code Playgroud) 在using语句中使用内存流时,是否需要调用close?例如这里需要ms.Close()吗?
using (MemoryStream ms = new MemoryStream(byteArray))
{
// stuff
ms.Close();
}
Run Code Online (Sandbox Code Playgroud) 我在C#中解析一些XML.我从数据库中获取它,因此在使用XmlTextReader读取它之前将其转换为MemoryStream.问题是我得到了这个错误:Name cannot begin with the ' ' character, hexadecimal value 0x20. Line 1, position 3.以下是我的XML和我的代码用于阅读它(它是从数据库出来的,没有空白的第一个字符).有什么建议?
XML:
<? xml version="1.0" encoding="utf-8" ?>
<form>
<e order="0" type="custom" name="test">
<fi type="text" />
<o />
</e>
<e order="1" type="zip" />
<e order="2" type="state" />
</form>
Run Code Online (Sandbox Code Playgroud)
C#:
byte[] byteArray = new byte[formXml.Length];
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
byteArray = encoding.GetBytes(formXml);
MemoryStream xmlStream = new MemoryStream(byteArray);
XmlTextReader xmlReader = new XmlTextReader(xmlStream);
while (xmlReader.Read())
{
if (xmlReader.HasValue)
{
returnString += xmlReader.Depth.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
我认为它可能是编码,但我尝试过UTF8和ASCII,但找不到任何东西.
我知道,GetBuffer()在C#/一个MemoryStream.NET必须小心使用,因为,作为文档描述了这里,有可能在年底未使用的字节,所以你必须要确保只在第一MemoryStream的期待缓冲区中的.Length字节.
但后来我遇到了一个案例,其中缓冲区开头的字节是垃圾!实际上,如果您使用像反射器这样的工具并查看ToArray(),您可以看到:
public virtual byte[] ToArray()
{
byte[] dst = new byte[this._length - this._origin];
Buffer.InternalBlockCopy(this._buffer, this._origin, dst, 0,
this._length - this._origin);
return dst;
}
Run Code Online (Sandbox Code Playgroud)
所以要对返回的缓冲区做任何事情GetBuffer(),你真的需要知道_origin.唯一的问题是_origin是私有的,没有办法实现它......
所以我的问题是-什么是使用GetBuffer()在MemoryStream()无将MemoryStream是如何构造的一些先验知识(这是什么套_origin)?
(正是这个构造函数,只有这个构造函数,设置原点 - 当你想要一个字节数组的MemoryStream从字节数组中的特定索引开始时:
public MemoryStream(byte[] buffer, int index, int count, bool writable, bool publiclyVisible)
Run Code Online (Sandbox Code Playgroud)
)
以下代码有效,但我想知道MemoryStream创建是否正确关闭.应该如何执行或FileStreamResult为我处理它?
public FileStreamResult DownloadBudgetedRoleOpportunities(
Guid projectGuid,
IEnumerable<Guid> guidRequiredRoles)
{
var rolebroker = new ProjectRoleBudgetBroker();
var memstream = rolebroker.CreateBudgetedRoleOpportunies(
projectGuid,
guidRequiredRoles);
var fsr = new FileStreamResult ( memstream, "application/csv" )
{
FileDownloadName = "RoleOpportunities.csv"
};
// memstream.Close(); throws exception
return fsr;
}
Run Code Online (Sandbox Code Playgroud) 我有一个应用程序,当前正在创建一个文本文件导入到一个会计应用程序.它使用以下代码创建文件并向其写入行:
TextWriter tw = new StreamWriter(ExtractFileName);
tw.WriteLine("ref\tACCOUNT\tbatch\tDEBIT\tCREDIT\tDesc");
Run Code Online (Sandbox Code Playgroud)
我现在需要创建多个提取文件,并计划使用SharpZipLib(#ziplib)将它们压缩为单个.zip文件,并希望更改我的代码以在内存中创建文本文件,并使用它创建我的zip文件.我想我应该创建/使用MemoryStream但是无法弄清楚如何移植我现有的代码.
谢谢.
我们的软件通过a解压缩某些字节数据GZipStream,从a读取数据MemoryStream.这些数据以4KB的块解压缩并写入另一个MemoryStream.
我们已经意识到进程分配的内存远远高于实际的解压缩数据.
示例:具有2,425,536字节的压缩字节数组被解压缩为23,050,718字节.我们使用的内存分析器显示Method MemoryStream.set_Capacity(Int32 value)分配了67,104,936个字节.这是保留和实际写入内存之间的2.9倍.
注:MemoryStream.set_Capacity被称为从MemoryStream.EnsureCapacity它本身被称为MemoryStream.Write我们的功能.
为什么MemoryStream保留这么大的容量,即使它只附加4KB的块?
以下是解压缩数据的代码段:
private byte[] Decompress(byte[] data)
{
using (MemoryStream compressedStream = new MemoryStream(data))
using (GZipStream zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
using (MemoryStream resultStream = new MemoryStream())
{
byte[] buffer = new byte[4096];
int iCount = 0;
while ((iCount = zipStream.Read(buffer, 0, buffer.Length)) > 0)
{
resultStream.Write(buffer, 0, iCount);
}
return resultStream.ToArray();
}
}
Run Code Online (Sandbox Code Playgroud)
注意:如果相关,这是系统配置:
在Delphi 2009之前我们有以下代码:
function MemoryStreamToString(M : TMemoryStream): String;
var
NewCapacity: Longint;
begin
if (M.Size = > 0) or (M.Memory = nil) then
Result:= ''
else
begin
if TMemoryStreamProtected(M).Capacity = M.Size then
begin
NewCapacity:= M.Size+1;
TMemoryStreamProtected(M).Realloc(NewCapacity);
end;
NullString(M.Memory^)[M.Size]:= #0;
Result:= StrPas(M.Memory);
end;
end;
Run Code Online (Sandbox Code Playgroud)
我们如何使用Delphi 2009将此代码转换为支持Unicode?
我找不到任何现成的东西,所以我想出了:
class membuf : public basic_streambuf<char>
{
public:
membuf(char* p, size_t n) {
setg(p, p, p + n);
setp(p, p + n);
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
char *mybuffer;
size_t length;
// ... allocate "mybuffer", put data into it, set "length"
membuf mb(mybuffer, length);
istream reader(&mb);
// use "reader"
Run Code Online (Sandbox Code Playgroud)
我知道stringstream,但它似乎无法使用给定长度的二进制数据.
我在这里发明了自己的轮子吗?
编辑
我有一个HttpHandler返回一个图像Response.OutputStream.我有以下代码:
_imageProvider.GetImage().CopyTo(context.Response.OutputStream);
Run Code Online (Sandbox Code Playgroud)
GetImage()方法返回一个Stream实际上是MemoryStream实例的实例,它返回0个字节到浏览器.如果我更改GetImage()方法签名以返回a MemoryStream并使用以下代码行:
_imageProvider.GetImage().WriteTo(context.Response.OutputStream);
Run Code Online (Sandbox Code Playgroud)
它工作,浏览器获取图像.那么在MemoryStream类中WriteTo和CopyTo之间的区别是什么,以及Stream在GetImage()方法签名中使用class 的推荐方法是什么.
memorystream ×10
c# ×6
.net ×2
c++ ×1
delphi ×1
delphi-2009 ×1
getbuffer ×1
gzipstream ×1
httphandler ×1
memory ×1
stream ×1
string ×1
unicode ×1
using ×1
xml ×1