如何上传文件并将其保存到使用C#进一步preVIEW一个流? [英] How can I upload a file and save it to a Stream for further preview using C#?

查看:307
本文介绍了如何上传文件并将其保存到使用C#进一步preVIEW一个流?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有上传文件,将其保存到一个流的方式,此流我会暂时保存在一个会话,并在最后,我会尽量preVIEW这个上传的文件就是在这个会议? ?

Is there a way to upload a file, save it to a Stream, this Stream I will save it temporarily in a Session and, at last, I will try to preview this uploaded file that is in this Session??

例如,一个PDF文件。

For example, a pdf file.

谢谢!

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();

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

And in another method, I'm doing this:

byte[] imageByte = null;

imageByte = (byte[])Session["pdf"];

Response.ContentType = "application/pdf";
Response.Buffer = true;
Response.Clear();
Response.BinaryWrite(imageByte);

但没有happends ......我的浏览器,甚至打开一个页面NEM显示PDF文件,但表示说,该文件是不是PDF(或类似文件不与PDF发起一个窗口,我没T理解)

But nothing happends... my browser even opens a nem page to show the pdf file, but a window is shown saying that the file is not a pdf (or something like the file doesn't initiate with pdf, I didn't understand that)

推荐答案

当然是。我上传我的应用文件(PDF /图片)到我的分贝。我的模型对象实际存储文件的字节数组,但其他功能我不得不转换和从视频流,以便即时确定它一样容易保持在流格式。

Sure is. I upload files (PDF/images) to my db in my app. My model object actually stores the file as a byte array but for other functions i have to convert to and from streams so im sure its just as easy to keep it in stream format.

下面是一些code例子(复制粘贴ñ)从我的应用程序 -

Here are some code examples (copy n paste) from my app-

文件,我用它来移动文件(PDF文件/图片)对象周围:

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文件类型:

..the PdfDoc type specifically for PDF files:

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动作的例子:

.. an example of an action that receives multi-part POST for file uploading:

    //
    // 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回例如preVIEW视图。

Now you can see i pass the file object to my service here but you can choose to add it to the session and pass an id back to the 'preview' view for example.

最后,这里是一个通用的动作我用它来呈现出来的文件给客户端(你可以有类似的东西呈现文件从会话/流):

Finally, here is a generic action i use to render files out to the client (you could have something similar render the files/stream from the Session):

    //
    // GET: /FileManager/GetFile/ID
    [OutputCache(Order = 2, Duration = 600, VaryByParam = "ID")]
    public ActionResult GetFile(int ID)
    {
        FileService svc = ObjectFactory.GetInstance<FileService>();

        KsisOnline.Data.File result = svc.GetFileByID(ID);

        return File(result.Data, result.MimeType, result.UploadFileName);
    }

编辑:结果
我发现我需要更多的样本来解释上面 -


I noticed i need more samples to explain the above-

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

For the upload action above, the FileUploadResultDTO class:

    public class FileUploadResultDTO
    {
        public List<File> 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<File>();

        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, @"(/|\\)?(?<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;
    }

最后(我希望我现在需要的一切)这个的readFully 功能。这不是我的设计。我是从网上 - 流读取可能会非常棘手。我觉得这个功能是完全读取流最成功的方式:

And finally (i hope i have everything you need now) this ReadFully function. It's not my design. I got it from the net - stream reading can be tricky. I find this function is the most successful way to completely read a stream:

    /// <summary>
    /// 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.
    /// </summary>
    /// <param name="stream">The stream to read data from</param>
    /// <param name="initialLength">The initial buffer length</param>
    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;
    }

这篇关于如何上传文件并将其保存到使用C#进一步preVIEW一个流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆