Вопрос, с которым столкнулись разработчики, заключается в возникновении ошибки "Not Implemented" при попытке копирования файла из виртуальных папок Windows в среде Delphi 2007. Виртуальные папки — это специальные папки, созданные операционной системой для удобства доступа к определенным типам файлов, например, к изображениям с камеры или смартфона. Для работы с такими папками в Delphi используется компонент TAttachDialog, являющийся потомком TCustomFileOpenDialog, который предоставляет доступ к свойству ShellItems.
Описание проблемы
В коде, предоставленном пользователем, используется компонент TAttachDialog для выбора файла из виртуальной папки. После выбора файла, код пытается создать потоковый объект TFileStream для копирования содержимого файла. Однако, при выполнении операции копирования через метод CopyFrom возникает ошибка "Not Implemented".
Подробный анализ проблемы
Ошибка "Not Implemented" в контексте работы с потоками в Delphi может возникать по нескольким причинам. В частности, если класс, наследуемый от TStream, не переопределяет методы Seek для 32-битной и 64-битной архитектуры, то при вызове этих методов будет поднято исключение EStreamError. Компонент TOLEStream, используемый в примере, переопределяет 32-битную версию метода Seek, но не переопределяет свойство GetSize.
При попытке получить размер потока OStrm.Size перед копированием, вызывается метод GetSize, который, в свою очередь, использует метод Seek для определения размера потока. Если IStream, полученный в результате работы с TAttachDialog, не поддерживает случайный доступ, то его метод Seek возвращает E_NOTIMPL, что приводит к ошибке при попытке копирования.
Подтвержденное решение
Для решения проблемы необходимо изменить способ получения размера потока. Вместо использования GetSize, следует вызвать метод IStream.Stat, который возвращает структуру STATSTG, содержащую размер потока. Затем, полученный размер можно использовать для копирования содержимого потока в файл.
Пример кода
var
...
Stat: STATSTG;
begin
...
if Item.BindToHandler(Nil, BHID_Stream, IID_IStream, Strm) = S_OK then
try
OStrm := TOLEStream.Create(Strm);
try
FStrm := TFileStream.Create('C:\Temp\Test.jpg', fmCreate);
try
OleCheck(Strm.Stat(Stat, STATFLAG_NONAME));
if Stat.cbSize.QuadPart > 0 then
FStrm.CopyFrom(OStrm, Stat.cbSize.QuadPart);
finally
FreeAndNil(FStrm);
end;
finally
FreeAndNil(OStrm);
end;
finally
Strm := Nil;
end;
...
end;
Альтернативное решение
В качестве альтернативы можно избежать использования метода CopyFrom и скопировать байты вручную, выделив буфер и используя цикл для чтения данных из OStrm и записи в FStrm до тех пор, пока OStrm.Read не вернет, что данных больше нет.
Пример кода с ручным копированием
var
...
Buf: array[0..1023] of Byte;
NumRead: Integer;
begin
...
if Item.BindToHandler(Nil, BHID_Stream, IID_IStream, Strm) = S_OK then
try
OStrm := TOLEStream.Create(Strm);
try
FStrm := TFileStream.Create('C:\Temp\Test.jpg', fmCreate);
try
repeat
NumRead := OStrm.Read(Buf[0], SizeOf(Buf));
if NumRead <= 0 then
Break;
FStrm.WriteBuffer(Buf[0], NumRead);
until False;
finally
FreeAndNil(FStrm);
end;
finally
FreeAndNil(OStrm);
end;
finally
Strm := Nil;
end;
...
end;
Заключение
Используя один из предложенных методов, можно успешно скопировать файл из виртуальной папки в Delphi 2007, избегая ошибки "Not Implemented". Обратите внимание на правильное использование методов IStream и корректное управление ресурсами, чтобы избежать утечек памяти.
Вопрос связан с ошибкой 'Not Implemented' при копировании файла из виртуальных папок в среде разработки Delphi 2007 и предлагает решения, связанные с корректным использованием потоков и методов IStream.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.