2013-01-04 23 views
10

Sau khi loại bỏ một tập tin bằng cách sử dụng lớp System.IO.File:Làm thế nào để kiểm tra xem System.IO.File.Delete xóa một tập tin thành công

System.IO.File.Delete(openedPdfs.path); 

tôi cần phải chạy một số mã nếu tập tin đã bị xóa thành công . Miễn là phương thức không trả về bất kỳ giá trị nào, tôi sẽ kiểm tra xem tệp có tồn tại sau phương thức xóa hay không. Nếu nó vẫn tồn tại, tôi cho rằng chiến dịch đã thất bại.

Vấn đề là, phương pháp xóa hoạt động tốt, nhưng có một vài giây để xóa tệp. Hàm Exist trả về true vì tại thời điểm nó kiểm tra tệp có ở đó.

Làm cách nào để xác minh xem liệu System.IO.File.Delete(openedPdfs.path); có hoàn tất thành công hay không?

Code:

FileInfo file = new FileInfo(openedPdfs.path);  
System.IO.File.Delete(openedPdfs.path); 
if (file.Exists == false) 
{ ... } 
else 
{ ... } 
+1

"Cách thanh lịch nhất mà tôi có thể nghĩ đến là sử dụng một [FileSystemWatcher] (http: // MSDN. microsoft.com/en-us/library/system.io.filesystemwatcher.aspx) và đăng ký sự kiện 'Đã xóa' của nó." http://stackoverflow.com/questions/9370012/waiting-for-system-to-delete-file –

+3

Bạn có lo ngại về trường hợp khi xóa thành công, nhưng một tệp mới cùng tên được tạo trước khi kiểm tra của bạn cho sự tồn tại? – HABO

+0

@TimSchmelter FileSystemWatcher đã được báo cáo để thả các sự kiện đang tải. Một số người đã gợi ý rằng nó có thể được sử dụng để cải thiện khả năng đáp ứng, nhưng họ vẫn thăm dò ý kiến ​​tại một khoảng thời gian giảm để chắc chắn không bỏ lỡ các sự kiện. FSW cũng có thể kéo hiệu suất xuống, đặc biệt nếu các bộ lọc không cần thiết thô. –

Trả lời

4

Delete nên ném một ngoại lệ nếu các tập tin không được xóa. Do đó, cuộc gọi của bạn tới Exists là không cần thiết.

Hãy xem qua số documentation for Delete.

+2

Có một chút chậm trễ khi File.Delete hoàn thành khi tệp thực sự bị xóa. – tofutim

+12

-1: Câu đầu tiên của bạn là sai. Xóa không ném khi tệp chưa tồn tại trước đó (và do đó không bị xóa). Xem xét kỹ hơn tài liệu cho Xóa: "Nếu tệp bị xóa không tồn tại, không có ngoại lệ nào được ném." – mkf

0

Nó sẽ không ném ngoại lệ nếu tệp không tồn tại. Trong trường hợp lỗi nó sẽ ném ngoại lệ nếu nó không thể bị xóa, kiểm tra File.Delete

+0

Tài liệu cho biết "Nếu tệp bị xóa không tồn tại, không có ngoại lệ nào được ném." –

+0

@MobyDisk đúng, nhưng tôi có nghĩa là nó sẽ ném ngoại lệ trong trường hợp lỗi. Về mặt kỹ thuật, xóa tệp không tồn tại không phải là lỗi. – Zbigniew

0

Bạn luôn có thể sử dụng

System.IO.File.Exists(path) 

Mặc dù tôi đồng ý với Daniel, nếu Xóa không ném ngoại lệ bạn nên tốt.

1

Điều này phụ thuộc vào câu trả lời của Daniel A. White: Chúng tôi có thể thấy the signature for the methodpublic static void Delete(string path). Vì vậy, rõ ràng, bạn sẽ không nhận được phản hồi từ cuộc gọi Xóa trừ ngoại lệ. Nhưng giả sử bạn có tệp được viết hoặc cập nhật định kỳ theo một quy trình khác:

  1. Chương trình của bạn xóa thành công tệp.
  2. Quy trình khác sẽ tạo lại ngay sau khi xóa.
  3. Thử nghiệm chương trình của bạn để tồn tại với file.Exists. Có một tệp mới có cùng tên, do đó trả về đúng sự thật. Bạn đang đi xuống con đường sai.

Kịch bản chính xác này có thể không đúng đối với sự cố bạn đang cố giải quyết, nhưng kiểm tra xem liệu cuộc gọi Xóa đã ném ngoại lệ mạnh hơn nhiều so với việc triển khai hiện tại của bạn hay không.

0

Từ các ý kiến ​​và đề nghị bạn nên có thể sử dụng sau đây để đạt được kết quả mong muốn của bạn

try { 
    FileInfo file = new FileInfo(openedPdfs.path);  
    System.IO.File.Delete(openedPdfs.path); 
    // if no exception is thrown then you should assume all has gone well and put 
    // your file successfully deleted code here. 
} catch /*(Specfic exceptions can be referenced here in separate catch blocks see Daniel A. White answer)*/ { 
    // If something bad happened and the file was not deleted put handling code here 
} finally { 
    // if some action needs to be taken regardless of whether the file was successfully deleted or not put 
    // that code here 
} 
12

Như những người khác đã chỉ ra, các phương pháp File.Delete sẽ ném một ngoại lệ trong trường hợp thất bại.

Những gì họ bỏ qua để chỉ ra là ngoại lệ sẽ được ném vào hầu như tất cả các trường hợp nhưng không có trong mọi trường hợp.Cụ thể, phương pháp File.Delete sẽ không ném ngoại lệ nếu tệp bị xóa không xảy ra đã tồn tại. (Duh? Họ đang nghĩ gì vậy?)

Vì vậy, bạn nên kiểm tra xem tệp có tồn tại trước để xóa nó hay không; nếu nó không tồn tại, bạn không nên làm gì cả. Nếu nó tồn tại, bạn nên gọi File.Delete, và nếu điều đó ném một ngoại lệ, sau đó một lần nữa, bạn không nên làm bất cứ điều gì, bởi vì các tập tin đã không bị xóa. Nếu không, bạn nên thực hiện các công cụ sau khi xóa thành công của bạn.

+0

Trong khi không phải là một nhà apologist MS, tôi nghĩ rằng các thiết kế .NET tránh ném ngoại lệ khi trong nhiều trường hợp người gọi không quan tâm như thế nào hoặc khi tập tin đã bị xóa. Ngoại lệ không phải là một cách rất hiệu quả để báo cáo một kết quả không thú vị lắm. Directory.Create theo cùng một mẫu. Một lần nữa nó giải quyết tình trạng cuộc đua bằng cách không báo cáo sự tồn tại trước của thư mục. Trong hầu hết các trường hợp sử dụng, nó không quan trọng. WinAPI xử lý điều này bằng cách báo cáo chính xác những gì đã làm hoặc không xảy ra trong một giá trị trả về số nguyên mà không ném một ngoại lệ tốn kém. –

+0

@AndrewDennison và tôi không có nghĩa là phải giải tán Microsoft trong mọi cơ hội, nhưng ngoại lệ trong. Net rất khủng khiếp và không cần thiết tốn kém, khiến họ phát triển ra quyết định thiết kế lame để tránh chi phí này. Làm thế nào để tôi biết chúng là không cần thiết tốn kém? Vâng, tôi không có một bằng chứng cho nó, nhưng ấn tượng mà tôi có sau nhiều năm lập trình trong mỗi ngôn ngữ, là ngoại lệ trong java, mặc dù tốn kém, không gần như tốn kém như trong dotNet. –

0

Tôi phát hiện ra rằng nếu bạn sử dụng phương pháp thể hiện FileInfo Delete() mà thuộc tính cá thể FileInfo Exists không được cập nhật.
Ví dụ mã sau sẽ ném ngoại lệ không tìm thấy tệp vì tệp đã bị xóa nhưng số thứ hai if (output_file.Exists) vẫn đánh giá là đúng.

FileInfo output_file; 
if (output_file.Exists) output_file.Delete(); 

FileStream fs; 
if (output_file.Exists) 
{ 
    fs = new FileStream(fi.FullName, FileMode.Open, FileAccess.ReadWrite); 
} 
else 
{ 
    fs = new FileStream(fi.FullName, FileMode.CreateNew, FileAccess.ReadWrite); 
} 

tôi thấy rằng việc tạo ra một FileInfo mới từ cái cũ cố định vấn đề:

FileInfo output_file; 
if (output_file.Exists) 
{ 
    output_file.Delete(); 
    output_file = new FileInfo(output_file.FullName);  
} 

FileStream fs; 
if (output_file.Exists) 
{ 
    fs = new FileStream(fi.FullName, FileMode.Open, FileAccess.ReadWrite); 
} 
else 
{ 
    fs = new FileStream(fi.FullName, FileMode.CreateNew, FileAccess.ReadWrite); 
} 
+1

Bạn có thể sử dụng 'output_file.Refresh()' để làm mới trạng thái của 'FileInfo'. Ngoài ra, làm thế nào để trả lời câu hỏi này? – BACON

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