我正在实现一个模块,用于将文件从客户端计算机上传到服务器。在服务器端,我使用的是WCF Soap服务。
为了以块的形式上传文件,我已经从Microsoft http://msdn.microsoft.com/en-us/library/aa717050.aspx实现了此示例。我已经能够在一个简单的场景中使它工作,所以它确实以块的形式上传文件。此分块模块使用WSDualHttpBinding。
我需要实现一项功能来重新上传文件,以防上传过程在上传特定文件时出于任何原因(用户选择,机器关闭等)停止。
在我的WCF服务中,我有一个处理服务器端文件写入的方法:
public void UploadFile(RemoteFileInfo request)
{
FileInfo fi = new FileInfo(Path.Combine(Utils.StorePath(), request.FileName));
if (!fi.Directory.Exists)
{
fi.Directory.Create();
}
FileStream file = new FileStream(fi.FullName, FileMode.Create, FileAccess.Write);
int count;
byte[] buffer = new byte[4096];
while ((count = request.FileByteStream.Read(buffer, 0, buffer.Length)) > 0)
{
file.Write(buffer, 0, count);
file.Flush();
}
request.FileByteStream.Close();
file.Position = 0;
file.Close();
if (request.FileByteStream != null)
{
request.FileByteStream.Close();
request.FileByteStream.Dispose();
}
}
当函数request.FileByteStream.Read(buffer,0,buffer.Length)被消耗时,分块模块正在发送块。
文件流初始化后,文件被锁定(这是初始化文件流进行写入时的正常行为),但我遇到的问题是我在执行发送/接收过程时停止上传过程,然后,分块模块使用的通道不会被取消,因此文件保持锁定,因为WCF服务仍在等待发送更多数据,直到发送超时到期(超时为1小时,因为我需要上传文件+ 2.5GB )。在下一次上传时,如果我尝试上传同一个文件,我在WCF服务上会收到异常,因为无法再为同一个文件初始化文件流。
我想知道是否有办法避免/删除文件锁,所以在下次运行时我可以重新上传同一个文件,即使以前的文件流已经锁定了文件。
任何帮助都会很感激,谢谢。
答案 0 :(得分:1)
我个人不喜欢这种解决方案。保持连接并不理想。
使用您的示例,您可以在2.5GB文件的一半,并且可以中止该过程。你最终遇到了上面的情况。更糟糕的是,您需要重新提交已提交的所有数据。
我会自己处理块的路径并将它们附加到同一文件服务器端。调用指示文件正在启动的WCF方法,以块为单位上载数据,然后在上载完成时调用另一种方法。如果您确信文件名是唯一的,那么您甚至可以通过单个方法调用来完成此操作。
类似的东西:
ulong StartFile(string filename) // This returns the data already uploaded
void UploadFile(string filename, ulong start, byte[] data)
void EndFile(string filename) // Just as a safety net
如果您不想按照上面列出的路线(它不直接回答您的问题),上述问题的简单解决方案是在您上传时使用临时文件名然后在上载完成后重命名该文件。无论如何,您应该采用这种方法来防止服务器上的应用程序在上传完成之前提取文件。