2011-12-27 18 views
5

Tôi có một ứng dụng hoạt động với ảnh chụp nhanh bộ nhớ vật lý (ví dụ, các tệp VMware VMEM). Trong số những thứ khác, nó có thể đọc các quy trình/mô-đun ra khỏi ảnh chụp bằng địa chỉ ảo thay vì địa chỉ vật lý. Điều này liên quan đến việc xây dựng lại mô-đun 4KB tại một thời điểm thông qua bảng trang, từ đó, có nghĩa là một số của các cuộc gọi đến phương thức Tìm kiếm() của Luồng.Làm cách nào để xử lý tệp cơ bản của Luồng?

Vì lý do tôi không chắc chắn, các cuộc gọi này đến Seek() làm giảm đáng kể mọi thứ. Kết quả là, tôi đang tìm kiếm một cách xung quanh họ - hoặc ít nhất, một cách xung quanh việc thực hiện Seek() được quản lý. Đoán tốt nhất của tôi là PInvoke SetFilePointer và làm việc trực tiếp với nó, nhưng để làm điều đó tôi cần lấy IntPtr/SafeFileHandle cho Stream. Tôi có một vài hạn chế:

  1. API tôi đang làm việc bị giới hạn trong .NET 3.5, do đó không may MemoryMappedFile không phải là một tùy chọn.

  2. Tôi không thể sử dụng một FileStream (đã có trường SafeFileHandle riêng có thể được truy cập với sự phản chiếu) hoặc PInvoke CreateFile() để xem ảnh chụp nhanh theo cách khác - API bao gồm một BinaryReader có độc quyền khóa trên ảnh chụp nhanh.

Tất nhiên, không giống như FileStream, cả BinaryReader lẫn Dòng cơ bản của nó đều không tham chiếu đến xử lý tệp. Nhưng chắc chắn người ta phải tồn tại? Trong trường hợp đó, làm thế nào để tôi có được nó?

+1

Loại 'Luồng' nào? Không phải tất cả các luồng đều có xử lý tệp. –

+2

MemoryMappedFile trong .NET 4.0 chỉ là trình bao bọc được quản lý xung quanh API gốc, bạn có thể triển khai nó mà không gặp nhiều rắc rối trong vòng 3,5 (do đó, tôi đã thấy nhiều triển khai hiện có). Điều đó nói rằng, nó âm thanh với tôi rằng bạn đang chủ yếu bị mắc kẹt với việc sử dụng hệ thống tập tin (ngoài một số bộ nhớ đệm thông minh). Tệp ánh xạ bộ nhớ cho đến nay cung cấp cho bạn kết quả nhanh nhất có thể trong kịch bản được mô tả của bạn (so với các giải pháp được cung cấp ngoài hộp). – Polity

+0

@John Saunders: Cảm ơn bạn, câu hỏi của bạn đã nhắc tôi xem xét lại lớp 'BinaryReader', trong đó tôi nhận ra rằng tôi chỉ cần downcast thuộc tính 'BaseStream' thành' FileStream', sau đó sử dụng sự phản chiếu để truy cập vào ' SafeFileHandle'. Tôi rất vui khi chọn câu trả lời đúng nếu bạn muốn viết nó lên. – Wayside

Trả lời

3

Không có tệp nào xử lý cho Stream vì đó là lớp trừu tượng. Một lớp thực hiện Stream có thể hoặc không thể sử dụng một tay cầm tập tin - FileStream, vì nó đọc dữ liệu từ một tệp, nhưng MemoryStream, chẳng hạn, không.

Để có được xử lý tập tin cơ bản (trong trường hợp này một SafeFileHandle) của một BinaryReaderStream là một FileStream, sử dụng phản ánh để truy cập private SafeFileHandle _handle, như vậy:

SafeFileHandle sfh = (SafeFileHandle)typeof(FileStream).GetField("_handle", BindingFlags.NonPublic | BindingFlags.Instance).GetValue((FileStream)YOUR_BINARY_READER.BaseStream) 

Trên một mặt lưu ý: không phải cuộc gọi trực tiếp đến SetFilePointer() cũng không phải MemoryMappedFile đã giúp trong trường hợp này. Có vẻ như không có cách nào nhanh chóng để xử lý truy cập đĩa ngẫu nhiên tại ổ đĩa tôi đang sử dụng nó (hàng triệu cuộc gọi liên tiếp).

1

Vì bạn có BinaryReader qua FileStream bạn có thể truy cập vào BaseStream của người đọc, đúc đó để FileStream và sau đó sử dụng SafeFileHandle tài sản công cộng của mình để truy cập xử lý. Một cái gì đó như thế này:

FileStream stream = (FileStream)(reader.BaseStream); 
//use stream.SafeFileHandle 
Các vấn đề liên quan