为什么MemoryStream构造函数需要Int?

时间:2014-09-04 21:59:30

标签: c# memorystream

根据我提供的错误消息提供的here解决方案(“根级别的数据无效。第1行,第1位”) - 更多关于我的信息记录了here的艰难记录,我尝试从此处更改我的服务器代码:

public async void SendInventoryXML(String userId, String pwd, String fileName)
{
    XDocument doc = XDocument.Load(await Request.Content.ReadAsStreamAsync());
    String saveLoc = String.Format(@"C:\HDP\{0}.xml", fileName);
    doc.Save(saveLoc);
}

......对此:

public async void SendInventoryXML(String userId, String pwd, String fileName)
{
    MemoryStream ms = new MemoryStream(await Request.Content.ReadAsStreamAsync());
    ms.Flush();
    ms.Position = 0;

    XDocument doc = XDocument.Load(ms);
    String saveLoc = String.Format(@"C:\HDP\{0}.xml", fileName);
    doc.Save(saveLoc);
}

...但是得到,“参数1:无法从'System.IO.Stream'转换为'int'”和“'System.IO的最佳重载方法匹配.MemoryStream.MemoryStream(int)'有一些无效的参数

为什么MemoryStream会将int视为arg?它/不应该真的需要一个字节数组或类似的东西吗?

4 个答案:

答案 0 :(得分:3)

MemoryStream支持各种构造函数,而不仅仅是一个需要int的构造函数:

MemoryStream()
MemoryStream(Byte[])
MemoryStream(Int32)
MemoryStream(Byte[], Boolean)
MemoryStream(Byte[], Int32, Int32)
MemoryStream(Byte[], Int32, Int32, Boolean)
MemoryStream(Byte[], Int32, Int32, Boolean, Boolean)

有关每个的完整说明,请参阅MSDN:

http://msdn.microsoft.com/en-us/library/system.io.memorystream.memorystream(v=vs.110).aspx

但是,如果不采用现有的Stream实例,您可以使用方法Stream.CopyTo()(以及Stream.CopyToAsync()用于基于异步的代码),该方法将从一个流复制到另一个流,例如:

var in_stream = await Request.Content.ReadAsStreamAsync();
var out_stream = new MemoryStream();

await in_stream.CopyToAsync(out_stream);

在您的代码示例中,您可能只是直接从输入流中读取,在此实例中使用MemoryStream似乎是多余的:

XDocument doc = XDocument.Load(in_stream);

我还应该指出,从不需要在Flush()实例上调用MemoryStream,这个调用完全是冗余的,因为数据会立即写入后台{无论如何{1}}。

答案 1 :(得分:2)

如果您想要将流复制到内存中,那么您无法为MemoryStream提供流,那么您需要创建一个空的内存流然后执行复制。

public async void SendInventoryXML(String userId, String pwd, String fileName)
{
    var stream = await Request.Content.ReadAsStreamAsync()
    MemoryStream ms = new MemoryStream();
    await stream.CopyToAsync(ms);
    //ms.Flush(); Not needed, Flush does nothing in MemoryStream. See: http://referencesource.microsoft.com/#mscorlib/system/io/memorystream.cs
    ms.Position = 0;

    XDocument doc = XDocument.Load(ms);
    String saveLoc = String.Format(@"C:\HDP\{0}.xml", fileName);
    doc.Save(saveLoc);
}

答案 2 :(得分:1)

你最好这样使用它:

var httpStream = await Request.Content.ReadAsStreamAsync();
MemoryStream ms = new MemoryStream();
httpStream.CopyTo(ms);

答案 3 :(得分:1)

是的,您可以传递一个字节数组。但看起来你正在传递一个任务而不是。也许像这样(未经测试的)代码可以使用(复制自:Working With System Threading Tasks):

public async void SendInventoryXML(String userId, String pwd, String fileName)
{
    Task task = Request.Content.ReadAsStreamAsync().ContinueWith(t =>
    {
        var stream = t.Result;
        using (FileStream fileStream = File.Create(String.Format(@"C:\HDP\{0}.xml", fileName), (int) stream.Length)) 
        {
            byte[] bytesInStream = new byte[stream.Length];
            stream.Read(bytesInStream, 0, (int) bytesInStream.Length);
            fileStream.Write(bytesInStream, 0, bytesInStream.Length);
        }
    });
}