如果我检查流的有效图像我不能写字节到服务器

Pet*_*ter 2 c# stream

在将文件上传到图像服务器之前,我正在尝试检查文件是否是图像.我正在使用以下函数执行此操作,该函数非常好用:

static bool IsValidImage(Stream imageStream)
            {
                bool isValid = false;
                try
                {
                    // Read the image without validating image data
                    using (Image img = Image.FromStream(imageStream, false, false))
                    {
                        isValid = true;
                    }
                }
                catch
                {
                    ;
                }
                return isValid;
            }
Run Code Online (Sandbox Code Playgroud)

问题是,当以后立即调用以下内容时,该行:

while ((bytesRead = request.FileByteStream.Read(buffer, 0, bufferSize)) > 0)
Run Code Online (Sandbox Code Playgroud)

evalueates为零,不读取任何字节.我注意到当我删除I​​sValidImage函数时,读取字节并写入文件.看来字节只能读一次?知道如何解决这个问题吗?

using (FileStream outfile = new FileStream(filePath, FileMode.Create))
                    {
                        const int bufferSize = 65536; // 64K
                        int bytesRead = 0;

                        Byte[] buffer = new Byte[bufferSize];

                        while ((bytesRead = request.FileByteStream.Read(buffer, 0, bufferSize)) > 0)
                        {
                            outfile.Write(buffer, 0, bytesRead);
                        }

                        outfile.Close(); //necessary?

                    }
Run Code Online (Sandbox Code Playgroud)

更新:感谢您的帮助Marc.我是流媒体操作新手,可以在这里使用更多帮助.我拍了一下,但可能会混淆使用filestream和memorystream.你介意看看吗?再次感谢.

using (FileStream outfile = new FileStream(filePath, FileMode.Create))
using (MemoryStream ms = new MemoryStream())
{

   byte[] buffer = new byte[1024];
   int bytesRead;

   while ((bytesRead = request.FileByteStream.Read(buffer, 0, buffer.Length)) > 0)
   {
         ms.Write(buffer, 0, bytesRead);
   }

   // ms now has a seekable/rewindable copy of the data

   // TODO: read ms the first time

   // I replaced request.FileByteStream with ms but am unsure about 
   // the using statement in the IsValidImage function.

   if (!IsValidImage(ms) == true)
   {
        ms.Close();
        request.FileByteStream.Close();
        return;
   }

   ms.Position = 0;

   // TODO: read ms the second time

   byte[] m_buffer = new byte[ms.Length];
   while ((bytesRead = ms.Read(m_buffer, 0, (int)ms.Length)) > 0)
   {
        outfile.Write(m_buffer, 0, bytesRead);
   }


 } 


 static bool IsValidImage(MemoryStream imageStream)
 {
            bool isValid = false;
            try
            {
                // Read the image without validating image data
                using (Image img = Image.FromStream(imageStream, false, false))
                {
                    isValid = true;
                }
            }
            catch
            {
                ;
            }
            return isValid;
    }
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 6

当您从任何流中读取时,位置会增加.如果你读到一个流到最后(通常),然后尝试再次读取,那么它将返回EOF.

对于某些流,您可以搜索 - Position例如,将其设置为0.但是,您应该尽量避免依赖于此,因为它不适用于许多流(特别是涉及网络IO时).您可以通过查询此功能CanSeek,但避免这种情况会更简单 - 部分就像您基于此分支一样,您突然有两倍的代码需要维护.

如果需要两次数据,则选项取决于数据的大小.对于小流,将其缓存在内存中,作为a byte[]或a MemoryStream.对于较大的流(或者如果您不知道大小),则写入临时文件(并在之后删除)是一种合理的方法.您可以根据需要多次打开和读取文件(串行,而不是并行).


如果你很高兴流不是太大(虽然可能添加上限以防止人们上传交换文件等):

using (MemoryStream ms = new MemoryStream()) {
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = inputStream.Read(buffer, 0, buffer.Length)) > 0) {
        ms.Write(buffer, 0, bytesRead);
    }

    // ms now has a seekable/rewindable copy of the data

    // TODO: read ms the first time
    ms.Position = 0;
    // TODO: read ms the second time
}
Run Code Online (Sandbox Code Playgroud)