【问题标题】:StreamWriter output BaseStream comes firstStreamWriter 输出 BaseStream 优先
【发布时间】:2016-03-15 01:19:47
【问题描述】:

我有下面的 SimpleHttp 服务器代码:

   using (Stream fs = File.Open(@"C:\Users\Mohamed\Desktop\Hany.jpg", FileMode.Open))
            {
                StreamWriter OutputStream = new StreamWriter(new BufferedStream(someSocket.GetStream()));
                OutputStream.WriteLine("HTTP/1.0 200 OK");
                OutputStream.WriteLine("Content-Type: application/octet-stream");
                OutputStream.WriteLine("Content-Disposition: attachment; filename=Hany.jpg");
                OutputStream.WriteLine("Content-Length: " + img.Length);
                OutputStream.WriteLine("Connection: close");
                OutputStream.WriteLine(""); // this terminates the HTTP headers

                fs.CopyTo(OutputStream.BaseStream);
                OutputStream.Flush();
                //OutputStream.BaseStream.Flush();
            }

问题是当我看到输出 http 响应时,标头位于文本的末尾,并且来自 BaseStream 的图像二进制文件甚至在标头之前排在第一位。输出示例是(当然我删除了图像的长字节):

    ä3ST)ëî!ðDFYLQ>qâ:oÂÀó?ÿÙHTTP/1.0 200 OK
    Content-Type: image/png
    Connection: close

我想要的是颠倒顺序并将标题放在顶部,得到的是这样的:

    HTTP/1.0 200 OK
    Content-Type: image/png
    Connection: close
    ä3ST)ëî!ðDFYLQ>qâ:oÂÀó?ÿÙT4ñ®KÛ'`ÃGKs\CGÔ«¾+L»ê±?0Íse3rïÁå·>"ܼ;®N¦Ãõ5¨LZµL¯

在流写入器或 BaseStream 上使用刷新无关紧要。 任何帮助!

【问题讨论】:

  • StreamWriter 有一个缓冲区,您必须在复制到其 BaseStream 之前对其进行 Flush()。复制之后再做为时已晚。

标签: c# .net filestream streamwriter


【解决方案1】:

谢谢 Kzrystof,我接受了你的提示,现在它可以在使用 copyTo 之前刷新 StreamWriter,但是我真的不知道这是否正确?你怎么看?

  using (Stream fs = File.Open(@"C:\Users\Mohamed\Desktop\Hany.jpg", FileMode.Open))
        {
            StreamWriter OutputStream = new StreamWriter(new BufferedStream(someSocket.GetStream()));
            OutputStream.WriteLine("HTTP/1.0 200 OK");
            OutputStream.WriteLine("Content-Type: application/octet-stream");
            OutputStream.WriteLine("Content-Disposition: attachment; filename=Hany.jpg");
            OutputStream.WriteLine("Content-Length: " + img.Length);
            OutputStream.WriteLine("Connection: close");
            OutputStream.WriteLine(""); // this terminates the HTTP headers
            OutputStream.Flush();

            fs.CopyTo(OutputStream.BaseStream);
            OutputStream.BaseStream.Flush();
            OutputStream.Flush();
        }

【讨论】:

    【解决方案2】:

    我认为问题是由调用 CopyTo 和传递 BaseStream 引起的。它可能会绕过尚未刷新数据的 StreamWriter。

    BaseStream 不应该用于写入。必须使用 StreamWriter。

    using (StreamWriter outputStream = new StreamWriter(new BufferedStream(someSocket.GetStream())))
     {
        outputStream.WriteLine("HTTP/1.0 200 OK");
        outputStream.WriteLine("Content-Type: application/octet-stream");
        outputStream.WriteLine("Content-Disposition: attachment; filename=Hany.jpg");
        outputStream.WriteLine("Content-Length: " + img.Length);
        outputStream.WriteLine("Connection: close");
        outputStream.WriteLine(""); // this terminates the HTTP headers
    
        string imageContent = Convert.ToBase64String(File.ReadAllBytes(@"C:\Users\Mohamed\Desktop\Hany.jpg"));
        outputStream.Write(imageContent);
        outputStream.Flush();
    }
    

    【讨论】:

    • 我没有使用 Stream 我将图像加载到字节数组并使用 stream.Write 但输出不完整。原始图像大小为 71KB,输出为 15 字节。 byte[] file = File.ReadAllBytes(@"C:\Users\Mohamed\Desktop\Hany.jpg"); OutputStream.Write(file);
    • 我意识到 StreamWriter 没有任何接受字节数组的 Write 方法。我已经用代码编辑了我的答案。
    • 感谢您的回复,但不幸的是,现在的输出是全尺寸的,但它完全是二进制的,而 Fiddler 正在抱怨它,并有一个糟糕的响应说它应该以 HTTP 开头/1.0 200 OK 并以 CRLF 结束标题部分。
    • 不客气。我们现在知道不能使用 BaseStream。我在答案中放回了 StreamWriter,并将图像的字节转换为 Base 64 编码。
    • 从技术上讲,最后一次编辑有效,但最后我得到了一个损坏的文件。你对我写的答案有什么看法?
    猜你喜欢
    • 2011-05-12
    • 2021-09-16
    • 1970-01-01
    • 2014-09-22
    • 1970-01-01
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多