2009-12-29 27 views
12

Có cách nào để bỏ qua hoặc xóa khóa tập tin được giữ bởi một chuỗi khác mà không làm hỏng chuỗi không?Có thể bỏ qua khóa tập tin trong C# khi một luồng/quy trình khác không nhất thiết sử dụng khóa độc quyền không?

Tôi đang sử dụng thư viện của bên thứ ba trong ứng dụng đang hoạt động chỉ đọc hoạt động trên một tệp. Tôi cần một chuỗi thứ hai đọc tệp cùng một lúc để trích xuất một số dữ liệu bổ sung mà thư viện của bên thứ ba không hiển thị. Thật không may, thư viện của bên thứ ba đã mở tệp bằng cách sử dụng khóa Đọc/Ghi và do đó tôi nhận được thông thường "Quy trình không thể truy cập tệp ... vì nó đang được sử dụng bởi một quy trình khác" ngoại lệ.

Tôi muốn tránh tải trước toàn bộ tệp bằng chuỗi của mình vì tệp lớn và sẽ gây ra sự chậm trễ không mong muốn trong quá trình tải tệp này và mức sử dụng bộ nhớ dư thừa. Sao chép tệp không thực tế do kích thước tệp. Trong quá trình hoạt động bình thường, hai luồng nhấn cùng một tệp sẽ không gây ra bất kỳ vấn đề về hiệu suất/sự cố IO nào đáng kể. Tôi không cần đồng bộ hóa thời gian hoàn hảo giữa hai luồng, nhưng chúng cần phải đọc cùng một dữ liệu trong vòng một nửa giây.

Tôi không thể thay đổi thư viện của bên thứ ba.

Có bất kỳ vấn đề nào đối với vấn đề này không?

+6

Khóa là khóa - nếu có, nó sẽ không bị khóa ... –

+1

Và giống như với nhiều khóa, có vẻ như một số nhà phát triển thư viện không hiểu rằng ít hơn là nhiều hơn. :-) Tôi cũng sẽ hài lòng với một công việc thông minh xung quanh. –

+4

Một shot dài: bạn có thể mở tệp đó dưới dạng chia sẻ _before_ thư viện bên thứ ba của bạn không? Có lẽ họ đã triển khai một số cơ chế dự phòng. –

Trả lời

5

Nếu bạn bắt đầu messing with the underlying file handle bạn có thể mở khóa các phần, sự cố là luồng truy cập tệp không được thiết kế để xử lý loại giả mạo này và có thể sẽ bị lỗi.

Đề xuất mạnh mẽ của tôi là vá thư viện của bên thứ ba, bất cứ điều gì bạn làm có thể và có thể sẽ phát nổ trong điều kiện thực tế.

1

Điều này không trực tiếp giải quyết tình huống của bạn, nhưng công cụ như Unlocker đạt được những gì bạn đang cố gắng làm, nhưng thông qua giao diện người dùng Windows.

2

Tóm lại, bạn không thể làm bất kỳ điều gì về việc khóa tệp bởi bên thứ ba. Bạn có thể nhận được ngay với câu trả lời của Richard E ở trên đề cập đến tiện ích Unlocker.

Khi bên thứ ba mở tệp và đặt khóa trên đó, hệ thống bên dưới sẽ cung cấp cho bên thứ ba đó một khóa để đảm bảo không có quy trình nào khác có thể truy cập. Có hai đoàn tàu suy nghĩ về điều này.

  • Sử dụng DLL injection để vá mã để đặt khóa hoặc đặt khóa rõ ràng. Điều này có thể nguy hiểm vì bạn sẽ rối tung với sự ổn định của một quá trình khác, và có thể kết thúc việc phá vỡ quy trình và gây ra sự đau buồn. Hãy suy nghĩ về nó, hệ thống cơ bản là theo dõi các tập tin được mở bởi một quá trình .. DLL tiêm vào thời điểm và vá mã - điều này đòi hỏi kiến ​​thức kỹ thuật để xác định quá trình bạn muốn tiêm vào thời gian chạy và thay đổi cờ khi chặn cuộc gọi API Win32 OpenFile(...).
  • Vì điều này đã được gắn thẻ là .NET, tại sao không tháo rời nguồn của bên thứ ba thành tệp .il và thay đổi cờ cho khóa để chia sẻ, xây dựng lại thư viện bằng cách biên dịch lại tất cả các tệp .il lại thành một tệp DLL . Điều này tất nhiên, sẽ yêu cầu để root xung quanh mã nơi mở tập tin đang diễn ra trong một số lớp học ở đâu đó.

Hãy xem podcast here. Và hãy xem ở đây giải thích cách thực hiện tùy chọn thứ hai được đánh dấu ở trên, here.

Hy vọng điều này sẽ giúp, Trân trọng, Tom.

1

Bất kỳ mức thấp hack để làm điều này có thể dẫn đến vỡ lở chủ đề, tập tin tham nhũng hoặc vv

Do đó tôi nghĩ rằng tôi muốn đề cập đến những điều tốt nhất tiếp theo, chỉ cần đợi đến lượt và cuộc bình chọn của bạn cho đến khi các tập tin không bị khóa: https://stackoverflow.com/a/11060322/495455


tôi không nghĩ rằng lời khuyên thứ 2 này sẽ giúp đỡ, nhưng điều gần gũi nhất (mà tôi biết) sẽ là DemandReadFileIO:

IntSecurity.DemandReadFileIO(filename); 

internal static void DemandReadFileIO(string fileName) 
{ 
    string full = fileName;    
    full = UnsafeGetFullPath(fileName); 
    new FileIOPermission(FileIOPermissionAccess.Read, full).Demand(); 
} 
1

Tôi nghĩ rằng đây là một vấn đề có thể được giải quyết bằng C++. Nó khó chịu nhưng ít nhất nó hoạt động (như đã thảo luận ở đây: win32 C/C++ read data from a "locked" file)

Các bước thực hiện:

  1. Mở tập tin trước khi thư viện thứ ba với fsopen và cờ _SH_DENYNO
  2. Mở nộp với thư viện thứ ba
  3. đọc các tập tin bên trong mã của bạn

bạn có thể quan tâm đến những liên kết này cũng như:

  1. Calling C++ từ C# (Possible to call C++ code from C#?)
  2. Các liên kết bên trong từ bài đăng này với một mẫu (http://blogs.msdn.com/b/borisj/archive/2006/09/28/769708.aspx)
1

Bạn đã cố gắng thực hiện một bản sao giả của tập tin trước khi thư viện của bên thứ ba của bạn nhận được một nắm giữ của nó ... sau đó sử dụng bản sao thực tế cho các thao tác của bạn, một cách hợp lý này sẽ chỉ được xem xét nếu các tập tin chúng ta đang nói về là khá nhỏ. nhưng nó là một loại lừa đảo :) chúc may mắn

1

Nếu tệp bị khóa và không được sử dụng, thì bạn có vấn đề với cách cơ chế khóa/mở khóa tệp của bạn hoạt động. Bạn chỉ nên khóa một tập tin khi bạn đang sửa đổi nó, và sau đó sẽ ngay lập tức mở khóa nó để tránh những tình huống như thế này.

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