我正在尝试在我的D:目录中保存图像,为了实现这一点,我将保存在Session
来自FileUpload
组件的一些信息。
在我的名为btnConfirm_Click
的方法中,我创建了Session
并在我的btnSave_Click
方法中恢复了此信息并尝试保存文件,但是当我签入{{1}时}目录,文件存在,但是当我打开这个文件时,我看到了消息:D:
有人可以帮助我吗?
C#代码
The windows photo viewer can not open this picture because the file appears to be damaged, corrupted, or is too big ..
答案 0 :(得分:5)
byte[] byteArray = Encoding.UTF8.GetBytes(Session["Content"].ToString());
这条线看起来非常错误。您正在使用字符串(编码为UTF8)并尝试将其转换为二进制JPG图像。这不行。您需要将原始图像保留为二进制(而不是文本+编码)形式。当您将byte[]
转换为string
(反之亦然)时会出现信息丢失,因为文本编码不能(通常)代表所有字节序列。
正如@PanagiotisKanovas所提到的,您希望得到Session['Content']
数据流。
顺便说一下,你没有关闭你的流,所以当你尝试打开文件时,对象仍然可以锁定。
using (FileStream fileStream = File.Create(sPath, (int)stream.Length)) {
byte[] bytesInStream = new byte[stream.Length];
stream.Read(bytesInStream, 0, bytesInStream.Length);
fileStream.Write(bytesInStream, 0, bytesInStream.Length);
}
答案 1 :(得分:1)
该消息表明该文件不包含图像数据。您的代码永远不会将文件的内容存储到磁盘。
它的作用是获取Stream(FileUpload.FileContent)对象的字符串表示形式(通常是该类型的名称)将此名称转换为Unicode字符串,然后尝试将其转换为二进制文件作为UFT8 string,最后将结果存储在一个文件中。
Session["Content"]
的内容是原始流,因此您只需使用Stream.CopyTo将一个流的内容复制到另一个,例如。
var sourceStream=(Stream)Session["Content"];
using(var fileStream=File.Create(targetPath,sourceStream.Length);
{
sourceStream.CopyTo(fileStream);
}
更好的是,根本不要使用Session。除非某些内容导致FileUpload1控件丢失其内容,否则在执行btnSave_Click处理程序时其内容仍然可用。在这种情况下,您可以使用FileUpload.Save将文件直接保存到磁盘。
此外,使用Session是存储文件数据的错误位置。会话使用计算机的内存或数据库来存储其数据,这会在您存储大量数据时导致性能下降。会话保持活动很长时间,这意味着即使您不再需要它,文件数据也会保留在内存中,除非您明确删除它。
答案 2 :(得分:0)
尝试将FileStream
包装在using语句中。
FileStream ref: http://msdn.microsoft.com/en-us/library/system.io.filestream.aspx
以下是对Streams的引用: http://msdn.microsoft.com/en-us/library/system.io.stream.aspx
为什么必须在using语句中包含此语句? 在代码中使用托管资源(如文件,数据库连接或此类任何其他类型)时,必须手动指定何时从托管堆(RAM)中释放这些资源。好吧,这不是100%有效的声明,因为这可以在垃圾收集开始时自动发生并删除所有未使用的对象。您必须了解一些要点才能了解应该编写哪种代码。
1)垃圾收集仅在内存压力上启动,而不是计时器
2)每个托管资源都是通过继承SafeHandle类来实现的。 http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.safehandle.aspx这个抽象类有一个名为Dispose()
的方法,其唯一的工作就是安全地释放它创建的任何托管资源。 dispose方法由垃圾收集器调用或手动调用时调用。例如,使用构造是以下代码的捷径:
var file;
try{ // code }
finally { file.Dispose(); }
PS:大多数时候你应该避免使用using
语句并调用Dispose()
。为什么?因为你有GC,所以让它完成他的工作。如果您遇到问题,则意味着您必须仔细查看代码。让GC做它最擅长的事情。最后,仅在您确定没有其他人使用您的托管资源时(例如在另一个线程中),仅使用using
或Dispose()
。