Перетащите большие виртуальные файлы из 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, чтобы даже знать синтаксис для этого. Любые советы / направления будут оценены!

Ответы на вопрос(2)

Ваш ответ на вопрос