在将文件上传到图像服务器之前,我正在尝试检查文件是否是图像.我正在使用以下函数执行此操作,该函数非常好用:
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为零,不读取任何字节.我注意到当我删除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?
}
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)
当您从任何流中读取时,位置会增加.如果你读到一个流到最后(通常),然后尝试再次读取,那么它将返回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)