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;
}