2012-04-18 26 views
10

Tôi đang triển khai một mô-đun để tải tệp lên theo các phần từ máy khách đến máy chủ. Ở phía máy chủ, tôi đang sử dụng dịch vụ WCF Soap.Tôi làm cách nào để mở khóa khóa FileStream?

Để tải tệp lên theo các phần, tôi đã triển khai mẫu này từ Microsoft http://msdn.microsoft.com/en-us/library/aa717050.aspx. Tôi đã có thể làm cho nó hoạt động trong một kịch bản đơn giản, do đó, nó tải lên các tập tin theo khối. Mô-đun chunking này đang sử dụng WSDualHttpBinding.

Tôi cần triển khai tính năng tải lên lại tệp trong trường hợp quá trình tải lên bị dừng vì bất kỳ lý do nào (lựa chọn của người dùng, tắt máy, v.v.) trong khi tệp cụ thể đó đang được tải lên.

Tại dịch vụ WCF của tôi, tôi có một phương pháp để xử lý các tập tin văn bản ở phía máy chủ:

khối
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(); 
} 
} 

Module chunking được gửi trong khi chức năng request.FileByteStream.Read (buffer, 0, đệm. Chiều dài) đang được tiêu thụ.

Sau khi luồng được khởi tạo, tệp bị khóa (đây là hành vi bình thường khi khởi tạo dòng ghi để viết), nhưng vấn đề tôi gặp phải là tôi ngừng quá trình tải lên trong khi quá trình gửi/nhận đang được thực hiện , sau đó kênh được sử dụng bởi mô-đun chunking không bị hủy, do đó, tệp sẽ bị khóa vì dịch vụ WCF vẫn đang chờ thêm dữ liệu được gửi, cho đến khi Thời gian chờ gửi hết hạn (thời gian chờ là 1 giờ kể từ khi tôi cần tải lên tệp +2.5 GB). Trong lần tải lên tiếp theo, nếu tôi cố gắng tải lên cùng một tệp, tôi nhận được ngoại lệ tại dịch vụ WCF vì không thể khởi chạy lại luồng phim cho cùng một tệp.

Tôi muốn biết nếu có cách nào để tránh/xóa khóa tệp, vì vậy lần chạy tiếp theo, tôi có thể tải lên lại cùng một tệp đó ngay cả khi luồng phim trước đó đã khóa tệp.

Bất kỳ trợ giúp nào sẽ đánh giá cao, Cảm ơn bạn.

+0

Là ['FileStream.Unlock'] (http://msdn.microsoft.com/en-us/library/system.io.filestream.unlock.aspx) của bất kỳ việc sử dụng nào ở đây? – Xenon

+0

Bạn có thể thử sử dụng hàm tạo FileStream với tham số SharingMode được đặt thành System.IO.FileShare.ReadWrite. –

+0

Tôi đã thử FileStream.Mở khóa nhưng nó không giải quyết vấn đề kể từ khi tập tin đã bị khóa bởi một quá trình trước đó trong một cuộc gọi WCF trước đó. – Fer

Trả lời

1

Tôi không thích loại giải pháp này. Duy trì kết nối không phải là lý tưởng.

Sử dụng ví dụ của bạn, bạn có thể là một nửa thông qua tệp 2.5GB và quy trình có thể bị hủy bỏ. Bạn kết thúc trong tình huống bạn có ở trên. Để làm cho vấn đề tồi tệ hơn, bạn cần phải gửi lại tất cả dữ liệu đã được gửi.

Tôi sẽ tự đi xử lý các khối và thêm chúng vào cùng một phía máy chủ tệp. Gọi một phương thức WCF cho biết một tệp đang bắt đầu, tải lên dữ liệu theo các khối và sau đó gọi một phương thức khác khi quá trình tải lên hoàn tất. NẾU bạn tin tưởng rằng các tên tập tin là duy nhất thì bạn thậm chí có thể thực hiện điều này với một cuộc gọi phương thức duy nhất.

Cái gì như:

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 

Một giải pháp đơn giản cho vấn đề trên của bạn nếu bạn không muốn đi con đường tôi nêu ở trên (nó không trả lời câu hỏi của bạn trực tiếp) là sử dụng một tập tin tạm thời trong khi bạn đang thực hiện tải lên và sau đó đổi tên tệp sau khi quá trình tải lên hoàn tất. Bạn thực sự nên áp dụng cách tiếp cận này để ngăn chặn một ứng dụng trên máy chủ tải lên tệp trước khi quá trình tải lên hoàn tất.

Các vấn đề liên quan