Перетащите большие виртуальные файлы из C # в Windows Explorer
У меня есть приложение C # WPF с разделом, который служит FTP-клиентом, перечисляет файлы на удаленном сервере и позволяет пользователю загружать их. Я хочу, чтобы пользователь мог перетаскивать файлы из списка файлов на свой компьютер (т. Е. В оболочку Windows Explorer).
Для этого я использовалКод VirtualFileDataObject из блога Задержки, с использованиемAction<Stream>
перегрузкаSetData
, Это прекрасно работает на небольших файлах.
Моя проблема в том, что некоторые из файлов, с которыми я имею дело, имеют очень большой размер (2+ ГБ) и способVirtualFileDataObject
Класс, обрабатывающий поток, включает чтение всего объекта в память, что может привести к выбрасыванию «недостаточно памяти». ошибка для этих очень больших файлов.
Соответствующий разделVirtualFileDataObject
код ниже.How can I rewrite this code to not require the entire stream to be in memory?
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>
Я предоставляю, который записывает фактические данные файла в поток. Мой делегат просто открывает файл и читает байты в предоставленный поток.
Есть ли способ избежать этого последнего шага, возможно, как-то передать поток файлов непосредственно для чтения из оболочки Explorer? Я думаю о заменеiStream
с указателем на файловый поток .NET, который я получил ... но я недостаточно знаю о взаимодействии COM, чтобы даже знать синтаксис для этого. Любые советы / направления будут оценены!