0

我正在尝试将图像保存在我的 D: 目录中,为此,我保存了组件中的Session一些信息FileUpload

在我调用的方法中,btnConfirm_Click我创建了我的方法Session,在我的btnSave_Click方法中,我恢复了这些信息并尝试保存文件,但是当我签入我的D:目录时,该文件存在,但是当我打开这个文件时,我看到了以下消息:The windows photo viewer can not open this picture because the file appears to be damaged, corrupted, or is too big ..

有人可以帮助我吗?

C# 代码

protected void btnConfirm_Click(object sender, EventArgs e)
{
 if (FileUpload1.HasFile)
            {
                string sFileName = FileUpload1.FileName;
                string fileExtension = System.IO.Path.GetExtension(sFileName).ToLower();
                foreach (string ext in new string[] { ".jpeg", ".jpg", ".png" })
                {
                    if (fileExtension == ext)
                    {
                        Session["Document"] = sFileName + fileExtension;
                        Session["Byte"] = FileUpload1.FileBytes;
                        Session["Content"] = FileUpload1.FileContent;
                        byte[] b = (byte[])Session["Byte"];
                    }
                }
           }
}


protected void btnSave_Click(object sender, EventArgs e)
        {
                if (Session["Document"].ToString() != null)
                {
                    try
                    {
                        byte[] byteArray = Encoding.UTF8.GetBytes(Session["Content"].ToString());                        
                        MemoryStream stream = new MemoryStream(byteArray);

                        sPath = "D:/123.jpg";
                        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);
                    }
                    catch
                    {
                    }
              }
         }
4

3 回答 3

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);
}
于 2013-07-11T12:09:18.563 回答
1

该消息说该文件不包含图像数据。您的代码永远不会将文件的内容存储到磁盘。

它所做的是获取 Stream ( FileUpload.FileContent ) 对象的字符串表示形式(通常是类型的名称)将此名称转换为 Unicode 字符串,然后尝试将其转换回二进制作为 UFT8 字符串,最后存储结果生成一个文件。

的内容是原始流,因此您可以使用Stream.CopyToSession["Content"]将一个流的内容复制到另一个流,例如。

var sourceStream=(Stream)Session["Content"];
using(var fileStream=File.Create(targetPath,sourceStream.Length);
{
    sourceStream.CopyTo(fileStream);
}

更好的是,根本不要使用 Session。除非某些原因导致 FileUpload1 控件丢失其内容,否则当您执行 btnSave_Click 处理程序时,其内容仍然可用。在这种情况下,您可以使用FileUpload.Save将文件直接保存到磁盘。

此外,使用 Session 是存储文件数据的错误位置。Session 使用机器的内存或数据库来存储其数据,当您在那里存储大量数据时,这可能会导致性能下降。会话会长时间保持活动状态,这意味着即使您不再需要文件数据,文件数据也会保留在内存中,除非您明确删除它。

于 2013-07-11T12:17:36.700 回答
0

尝试包装FileStreamin using 语句。

文件流参考: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 方法由垃圾收集器调用或在您手动调用它时调用。例如, using 构造是以下代码的快捷方式:

var file;
try{ // code }
finally { file.Dispose(); }

PS:大多数时候你应该避免using声明和调用Dispose(). 为什么?因为你有GC,让它完成他的工作。如果你有问题,这意味着你必须仔细查看你的代码。让 GC 做它最擅长的事情。最后,使用usingor Dispose()only,我的意思是,只有当您确定没有其他人在使用您的托管资源时(例如在另一个线程中)。

于 2013-07-11T12:09:05.663 回答