C# 如果我检查流中的有效图像,我可以';无法将字节写入服务器

C# 如果我检查流中的有效图像,我可以';无法将字节写入服务器,c#,stream,C#,Stream,在将文件上载到图像服务器之前,我正在尝试检查文件是否为图像。 我使用以下功能进行此操作,该功能工作异常出色: static bool IsValidImage(Stream imageStream) { bool isValid = false; try { // Read the image without validating ima

在将文件上载到图像服务器之前,我正在尝试检查文件是否为图像。 我使用以下功能进行此操作,该功能工作异常出色:

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;
            }
问题是,当随后立即调用以下命令时,该行:

while ((bytesRead = request.FileByteStream.Read(buffer, 0, bufferSize)) > 0)
evaluate为零,不读取任何字节。我注意到当我移除 IsValidImage函数,读取字节并写入文件。看来 字节只能读取一次?你知道怎么解决这个问题吗

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?

                    }

更新:谢谢你的帮助,马克。我是流操作新手,可以使用一点 这里有更多的帮助。我拍了一张照片,但可能混淆了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;
    }

从任何流读取时,位置都会增加。如果您将一个流读到底(这是典型的),然后再次尝试读取,那么它将返回EOF

对于某些流,您可以搜索-例如,将
位置设置为0。但是,您应该尽量避免依赖它,因为它对许多流都不可用(特别是当涉及网络IO时)。您可以通过
CanSeek
查询此功能,但避免此操作会更简单—部分原因是,如果您正在基于此进行分支,您突然需要维护的代码数量会增加一倍

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


如果您感到高兴,则流不会太大(尽管可能会添加一个上限以防止人们上载交换文件等):


实际上,流实例记住了当前“游标”的位置。有些流支持“倒带”。“CanSeek”属性随后将返回true。在HTTP请求的情况下,它将不起作用(CanSeek=false)

浏览器不也发送MIME类型吗


如果你真的想保持你的检查方式,你必须在更新中遵循Marc的建议,你在第二次读取流时会遇到问题

byte[] m_buffer = new byte[ms.Length];
while ((bytesRead = ms.Read(m_buffer, 0, (int)ms.Length)) > 0)
{
    outfile.Write(m_buffer, 0, bytesRead);
}
解决方案很简单:

byte[] m_buffer = ms.ToArray();
outfile.Write(m_buffer, 0, m_buffer.Length);

另请参见

谢谢,弗兰克。好吧,我不喜欢我的检查方式。我喜欢它很简单,在测试中,它看起来很防弹。但是,我不太喜欢创建一个临时文件来进行写/读操作,以检查类型的有效性。你能推荐另一种方法来检查图像(gif、tiff、png、jpg、bmp)而不必写入临时文件吗?你可以复制到@Frank-如果你高兴数据不是太大,也许只是内存中的缓冲区-请参阅我的UpdateAnks Marc-我上面的回答。因为我是新来的,你能看一下吗?非常感谢您的帮助。在第一个循环中,“inputStream”需要替换为实际的“request.FileByTestStream”;在第二次和第三次使用中,“request.FileByteStream”需要替换为“ms”。i、 例如,您首先从请求流读取到本地缓冲区(在此之后,请求为空)-然后要验证图像,并上载图像,您从本地缓冲区(也称为“ms”)读取。再次感谢Marc。我发布了,然后意识到我的错误,并在你写了上述内容后重新发布。我这里的东西有意义吗?现在是凌晨3点,我正在退色,所以我明天会回来查看。再次感谢您的帮助。请注意,我已经发布了您的更新问题的答案。谢谢Marc,我在问题中的回答。谢谢Mac-现在已排序。谢谢configurator,为我节省了很多时间。非常感谢。
byte[] m_buffer = ms.ToArray();
outfile.Write(m_buffer, 0, m_buffer.Length);
public static bool IsImagen(System.IO.Stream stream, String fileName)
{
        try
        {
            using (Image img = Image.FromStream(stream, false, false))
            {
                if (fileName.ToLower().IndexOf(".jpg") > 0)
                    return true;
                if (fileName.ToLower().IndexOf(".gif") > 0)
                    return true;
                if (fileName.ToLower().IndexOf(".png") > 0)
                    return true;
            }
        }
        catch (ArgumentException){}
        return false;
}