文件上传与c#和流

时间:2021-10-01 18:59:50

Looking at the different ways to upload a file in .NET, e.g. HttpPostedFile, and using a HttpHandler, I'm trying to understand how the process works in a bit more details.

看看在。net中上传文件的不同方式,例如HttpPostedFile和使用HttpHandler,我试图更详细地了解这个过程是如何工作的。

Specifically how it writes the information to a file.

特别是它如何将信息写入文件。

Say I have the following:

假设我有以下几点:

HttpPostedFile file = context.Request.Files[0];
file.SaveAs("c:\temp\file.zip");

The actual file does not get created until the full stream seems to be processed.

直到似乎要处理整个流时,才会创建实际的文件。

Similarly:

类似的:

using (Stream output = File.OpenWrite("c:\temp\file.zip"))
                    using (Stream input = file.InputStream)
                    {
                        byte[] buffer = new byte[8192];
                        int bytesRead;
                        while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            output.Write(buffer, 0, bytesRead);
                        }
                    }

I would have thought that this would "progressively" write the file as it reads the stream. Looking at the filesystem, it does not seems to do this at all. If I breakpoint inside the while, it does though.

我本以为这会在文件读取流时“逐步”编写文件。看一下文件系统,它似乎根本就不这么做。如果我在while内部断点,它会。

What I'm trying to do, is have it so you upload a file (using a javascript uploader), and poll alongside, whereby the polling ajax request tries to get the fileinfo(filesize) of the uploaded file every second. However, it always returns 0 until the upload is complete.

我要做的是,让它让您上传一个文件(使用javascript上传程序),并在此轮询ajax请求试图每秒获取上传文件的fileinfo(filesize)。但是,它总是返回0,直到上传完成。

Vimeo seems to be able to do this type of functionality (for IE)?? Is this a .NET limitation, or is there a way to progressively write the file from the stream.

Vimeo似乎能够完成这种类型的功能(用于IE)?这是. net的限制,还是有一种方法可以从流中逐步写入文件?

1 个解决方案

#1


2  

Two points:

两个点:

First, in Windows, the displayed size of a file is not updated constantly. The file might indeed be growing continually, but the size only increases once.

首先,在Windows中,文件的显示大小不会经常更新。该文件可能确实在不断增长,但是大小只会增加一次。

Second (more likely in this case), the stream might not be flushing to the disk. You could force it to by adding output.Flush() after the call to output.Write(). You might not want to do that, though, since it will probably have a negative impact on performance.

其次(在这种情况下更有可能),流可能不会刷新到磁盘。您可以通过在调用output.Write()之后添加output.Flush()来强制它。不过,您可能不想这样做,因为这可能会对性能产生负面影响。

Perhaps you could poll the Length property of the output stream directly, instead of going through the file system.

也许您可以直接轮询输出流的长度属性,而不是遍历文件系统。

EDIT:

编辑:

To make the Length property of the stream accessible to other threads, you could have a field in your class and update it with each read/write:

为了让其他线程能够访问流的长度属性,您可以在类中设置一个字段,并在每次读/写时更新该字段:

private long _uploadedByteCount;

void SomeMethod()
{
    using (Stream output = File.OpenWrite("c:\temp\file.zip"))
    using (Stream input = file.InputStream)
    {
        byte[] buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            output.Write(buffer, 0, bytesRead);
            Interlocked.Add(ref _uploadedByteCount, bytesRead);
        }
    }
}

public long GetUploadedByteCount()
{
    return _uploadedByteCount;
}

#1


2  

Two points:

两个点:

First, in Windows, the displayed size of a file is not updated constantly. The file might indeed be growing continually, but the size only increases once.

首先,在Windows中,文件的显示大小不会经常更新。该文件可能确实在不断增长,但是大小只会增加一次。

Second (more likely in this case), the stream might not be flushing to the disk. You could force it to by adding output.Flush() after the call to output.Write(). You might not want to do that, though, since it will probably have a negative impact on performance.

其次(在这种情况下更有可能),流可能不会刷新到磁盘。您可以通过在调用output.Write()之后添加output.Flush()来强制它。不过,您可能不想这样做,因为这可能会对性能产生负面影响。

Perhaps you could poll the Length property of the output stream directly, instead of going through the file system.

也许您可以直接轮询输出流的长度属性,而不是遍历文件系统。

EDIT:

编辑:

To make the Length property of the stream accessible to other threads, you could have a field in your class and update it with each read/write:

为了让其他线程能够访问流的长度属性,您可以在类中设置一个字段,并在每次读/写时更新该字段:

private long _uploadedByteCount;

void SomeMethod()
{
    using (Stream output = File.OpenWrite("c:\temp\file.zip"))
    using (Stream input = file.InputStream)
    {
        byte[] buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            output.Write(buffer, 0, bytesRead);
            Interlocked.Add(ref _uploadedByteCount, bytesRead);
        }
    }
}

public long GetUploadedByteCount()
{
    return _uploadedByteCount;
}