如何上传文件并将其保存到Stream以便使用C#进一步预览?

有没有办法上传文件,将其保存到Stream,这个Stream我会暂时保存在Session中,最后,我会尝试预览这个Session中的上传文件?

例如,pdf文件。

谢谢!!

EDITED

这是我正在尝试做的事情:

HttpPostedFileBase hpf = Request.Files[0] as HttpPostedFileBase; byte[] buffer = new byte[hpf.InputStream.Length]; MemoryStream ms = new MemoryStream(buffer); ms.Read(buffer, 0, (int)ms.Length); Session["pdf"] = ms.ToArray(); ms.Close(); 

在另一种方法中,我这样做:

 byte[] imageByte = null; imageByte = (byte[])Session["pdf"]; Response.ContentType = "application/pdf"; Response.Buffer = true; Response.Clear(); Response.BinaryWrite(imageByte); 

但没有任何事情发生…我的浏览器甚至打开一个nem页面来显示pdf文件,但是会显示一个窗口,说该文件不是pdf(或者文件不是用pdf启动的,我不明白那)

当然可以。 我在我的应用程序中将文件(PDF /图像)上传到我的数据库。 我的模型对象实际上将文件存储为字节数组,但对于我必须转换为流和从流转换的其他函数,所以我确保它以流格式保存它也很容易。

以下是我的应用程序中的一些代码示例(复制n粘贴)

我用来移动文件(PDF /图像)的File对象:

 public class File : CustomValidation, IModelBusinessObject { public int ID { get; set; } public string MimeType { get; set; } public byte[] Data { get; set; } public int Length { get; set; } public string MD5Hash { get; set; } public string UploadFileName { get; set; } } 

..PDfDoc类型专门用于PDF文件:

 public class PdfDoc : File { public int ID { get; set; } public int FileID { get { return base.ID; } set { base.ID = value; } } [StringLength(200, ErrorMessage = "The Link Text must not be longer than 200 characters")] public string LinkText { get; set; } public PdfDoc() { } public PdfDoc(File file) { MimeType = file.MimeType; Data = file.Data; Length = file.Length; MD5Hash = file.MD5Hash; UploadFileName = file.UploadFileName; } public PdfDoc(File file, string linkText) { MimeType = file.MimeType; Data = file.Data; Length = file.Length; MD5Hash = file.MD5Hash; UploadFileName = file.UploadFileName; LinkText = linkText; } } 

..一个接收多部分POST进行文件上传的动作示例:

  // // POST: /Announcements/UploadPdfToAnnouncement/ID [KsisAuthorize(Roles = "Admin, Announcements")] [AcceptVerbs(HttpVerbs.Post)] public ActionResult UploadPdfToAnnouncement(int ID) { FileManagerController.FileUploadResultDTO files = FileManagerController.GetFilesFromRequest((HttpContextWrapper)HttpContext); if (String.IsNullOrEmpty(files.ErrorMessage) && files.TotalBytes > 0) { // add SINGLE file to the announcement try { this._svc.AddAnnouncementPdfDoc( this._svc.GetAnnouncementByID(ID), new PdfDoc(files.Files[0]), new User() { UserName = User.Identity.Name }); } catch (ServiceExceptions.KsisServiceException ex) { // only handle our exceptions base.AddErrorMessageLine(ex.Message); } } // redirect back to detail page return RedirectToAction("Detail", "Announcements", new { id = ID }); } 

现在您可以看到我将文件对象传递给我的服务,但您可以选择将其添加到会话中并将ID传回“预览”视图。

最后,这是一个用于将文件呈现给客户端的通用操作(您可以使用类似的方式呈现来自Session的文件/流):

  // // GET: /FileManager/GetFile/ID [OutputCache(Order = 2, Duration = 600, VaryByParam = "ID")] public ActionResult GetFile(int ID) { FileService svc = ObjectFactory.GetInstance(); KsisOnline.Data.File result = svc.GetFileByID(ID); return File(result.Data, result.MimeType, result.UploadFileName); } 

编辑:
我注意到我需要更多的样品来解释上述情况 –

对于上面的上传操作, FileUploadResultDTO类:

  public class FileUploadResultDTO { public List Files { get; set; } public Int32 TotalBytes { get; set; } public string ErrorMessage { get; set; } } 

GetFilesFromRequest函数:

  public static FileUploadResultDTO GetFilesFromRequest(HttpContextWrapper contextWrapper) { FileUploadResultDTO result = new FileUploadResultDTO(); result.Files = new List(); foreach (string file in contextWrapper.Request.Files) { HttpPostedFileBase hpf = contextWrapper.Request.Files[file] as HttpPostedFileBase; if (hpf.ContentLength > 0) { File tempFile = new File() { UploadFileName = Regex.Match(hpf.FileName, @"(/|\\)?(?[^(/|\\)]+)$").Groups["fileName"].ToString(), // to trim off whole path from browsers like IE MimeType = hpf.ContentType, Data = FileService.ReadFully(hpf.InputStream, 0), Length = (int)hpf.InputStream.Length }; result.Files.Add(tempFile); result.TotalBytes += tempFile.Length; } } return result; } 

最后(我希望我现在拥有你需要的一切)这个ReadFullyfunction。 这不是我的设计。 我从网上得到它 – 流阅读可能很棘手。 我发现这个函数是完全读取流的最成功的方法:

  ///  /// Reads data from a stream until the end is reached. The /// data is returned as a byte array. An IOException is /// thrown if any of the underlying IO calls fail. ///  /// The stream to read data from /// The initial buffer length public static byte[] ReadFully(System.IO.Stream stream, long initialLength) { // reset pointer just in case stream.Seek(0, System.IO.SeekOrigin.Begin); // If we've been passed an unhelpful initial length, just // use 32K. if (initialLength < 1) { initialLength = 32768; } byte[] buffer = new byte[initialLength]; int read = 0; int chunk; while ((chunk = stream.Read(buffer, read, buffer.Length - read)) > 0) { read += chunk; // If we've reached the end of our buffer, check to see if there's // any more information if (read == buffer.Length) { int nextByte = stream.ReadByte(); // End of stream? If so, we're done if (nextByte == -1) { return buffer; } // Nope. Resize the buffer, put in the byte we've just // read, and continue byte[] newBuffer = new byte[buffer.Length * 2]; Array.Copy(buffer, newBuffer, buffer.Length); newBuffer[read] = (byte)nextByte; buffer = newBuffer; read++; } } // Buffer is now too big. Shrink it. byte[] ret = new byte[read]; Array.Copy(buffer, ret, read); return ret; } 

是的,但您无法将其保存为流。 流不包含任何数据,它只是访问实际存储的方法。

将数据作为字节数组获取,然后将其放入会话变量中,将其另存为文件,并将其作为响应发送。

使用BinaryReader将输入流中的数据获取到字节数组:

 byte[] data; using (BinaryReader reader = new BinaryReader(uploadedFile.InputStream)) { data = reader.ReadBytes((int) uploadedFile.InputStream.Length); } 

(编辑:从StreamReader更改为BinaryReader)