我有一個C#WPF應用程序,其中有一節用作FTP客戶端,列出遠程服務器上的文件並允許用戶下載它們。我希望用戶能夠將文件從文件列表中拖放到他們自己的機器上(即進入Windows資源管理器的shell)。將C#中的大型虛擬文件拖放到Windows資源管理器中
爲了實現這個目標,我使用了VirtualFileDataObject code from Delay's blog,使用的SetData
過載。這對小文件很有效。
我的問題是:我正在處理的一些文件非常大(2+ GB),VirtualFileDataObject
類處理流的方式涉及將整個事件讀入內存,最終可能會拋出「沒有足夠的存儲「錯誤,這些非常大的文件。
VirtualFileDataObject
代碼的相關部分如下。 我該如何重寫這段代碼,不要求整個流在內存中?
public void SetData(short dataFormat, int index, Action<Stream> streamData) {
_dataObjects.Add(
new DataObject {
FORMATETC = new FORMATETC {
cfFormat = dataFormat,
ptd = IntPtr.Zero,
dwAspect = DVASPECT.DVASPECT_CONTENT,
lindex = index,
tymed = TYMED.TYMED_ISTREAM
},
GetData =() => {
// Create IStream for data
var ptr = IntPtr.Zero;
var iStream = NativeMethods.CreateStreamOnHGlobal(IntPtr.Zero, true);
if (streamData != null) {
// Wrap in a .NET-friendly Stream and call provided code to fill it
using (var stream = new IStreamWrapper(iStream)) {
streamData(stream);
}
}
// Return an IntPtr for the IStream
ptr = Marshal.GetComInterfaceForObject(iStream, typeof(IStream));
Marshal.ReleaseComObject(iStream);
return new Tuple<IntPtr, int>(ptr, NativeMethods.S_OK);
},
});
}
特別地,GetData
此部分是罪魁禍首:
// Wrap in a .NET-friendly Stream and call provided code to fill it
using (var stream = new IStreamWrapper(iStream)) {
streamData(stream);
}
streamData
是Action<stream>
我提供一種實際的文件數據寫入到流。我的委託只是打開一個文件並將字節讀入提供的流中。
有沒有辦法避免這最後一步,或許以某種方式直接傳遞文件流以通過資源管理器shell讀取?我想用一個指向.NET文件流的指針代替iStream
...但我對COM互操作知之甚少,甚至不知道這樣做的語法。任何提示/方向將不勝感激!
僅供參考我在這裏回答了同樣的問題:HTTP://計算器。COM /問題/ 22700195 /拖和下拉式大虛擬文件與 - istream的-使用,virtualfiledataobject –