Текущий архив: 2003.07.17;
Скачать: CL | DM;
ВнизКак инициализировать переменную типа IStream ? Найти похожие ветки
← →
avkiev (2003-07-03 15:37) [0]Мне нужно текстовый буфер переписать в переменную типа IStream.
var st: IStream;
buf: pchar;
...
st.Write(buf, n, @n);
Тут возникает ошибка. Вероятно из-за того, что st не инициализирована. Как это побороть или как текстовый буфер скопировать в IStream ?
Заранее всем спасибо
← →
Некто (2003-07-03 15:43) [1]Зачем???!!!!
IStream - это интерфейс. Вам нужно почитать литературу по COM. А вообще опишите, что именно Вам нужно. Обязательно подскажу.
← →
avkiev (2003-07-03 15:52) [2]Нужно обмениваться данными между буфером из байт и потоком.
Поток в буфер - легко:
buf := AllocMem(n);
st.Read(buf, n, @n);
А вот буфер в поток - не получается :(
← →
avkiev (2003-07-03 15:52) [3]Нужно обмениваться данными между буфером из байт и потоком.
Поток в буфер - легко:
buf := AllocMem(n);
st.Read(buf, n, @n);
А вот буфер в поток - не получается :(
← →
Serginio (2003-07-03 16:03) [4]Применяй TStreamAdapter с СОМ объектами где требуется IStream
на пример.
procedure TForm1.SaveHTMLSourceToFile(const FileName: string;
WB: TWebBrowser);
var
PersistStream: IPersistStreamInit;
FileStream: TFileStream;
Stream: IStream;
SaveResult: HRESULT;
begin
PersistStream := WB.Document as IPersistStreamInit;
FileStream := TFileStream.Create(FileName, fmCreate);
try
Stream := TStreamAdapter.Create(FileStream, soReference) as IStream;
SaveResult := PersistStream.Save(Stream, True);
if FAILED(SaveResult) then
MessageBox(Handle, "Fail to save HTML source", "Error", 0);
finally
{ В ответ на уничтожение объекта TFileStream, передаём
soReference в конструктор TStreamAdapter. }
FileStream.Free;
end;
end;
← →
avkiev (2003-07-03 16:31) [5]Serginio и Некто, большое спасибо - все получилось
← →
avkiev (2003-07-03 18:43) [6]К сожалению все не так просто. Мне надо дисковый файл скопировать в виртуальный (комовский).
// Это фрагмент TLB-файла
procedure TDMP.PutFile(const path: WideString; const content: IUnknown);
begin
DefaultInterface.PutFile(path, content);
end;
...
// А это моя программа
var st: IStream;
f: TFileStream;
...
f := TFileStream.Create(filename1, fmOpenRead);
st := TStreamAdapter.Create(f, soReference) as IStream;
TDMP.PutFile(filename2, st);
f.Free;
end;
Копирование происходит, но через пару минут этот новый файл теряет свои атрибуты и становится недоступным.
Правильно ли я создал st ? В чем разница между soReference и soOwned ?
Нужно ли освобождать st ? Как ?
Нужно ли освобождать f ? Когда ?
← →
Serginio (2003-07-03 18:51) [7]Смотри
destructor TStreamAdapter.Destroy;
begin
if FOwnership = soOwned then
begin
FStream.Free;
FStream := nil;
end;
inherited Destroy;
end;
Если soOwned тебе не нужно заботиться об уничтожении стрима, иначе забота о уничтожении лежит на тебе.
Открываешь ты его как fmOpenRead а нужно
fmOpenReadReadWrite or fmCreate. Смотри справку по TFileStream.Create
← →
avkiev (2003-07-03 18:59) [8]
> Открываешь ты его как fmOpenRead а нужно
> fmOpenReadReadWrite or fmCreate. Смотри справку по TFileStream.Create
Почему ? Я же исходный файл открываю для чтения, а не целевой
← →
Serginio (2003-07-03 19:11) [9]Если судить по коду
TDMP.PutFile(filename2, st); То ты закачиваешь из filename2 в st, или наоборот???? Если да то fmOpenReadWrite .
Универсальный fmOpenReadWrite or fmCreate or fmShareDenyWrite
Ты дописываешь в файл
← →
avkiev (2003-07-04 10:15) [10]Не, я пишу из st в filename2
← →
Serginio (2003-07-04 12:38) [11]>>Мне надо дисковый файл скопировать в виртуальный (комовский).
У тебя комовский как раз st и является. Если тебе нужно записать в файл из st то зачем использовать TDMP.PutFile если можно просто
f2:=TFileStream.Create(filename2,fmOpenReadWrite or fmCreate);
f2.CopyFrom(f);
f.Free;
f2.Free;
Если нужно использовать IStream как Tstream используй TOleStream.
← →
avkiev (2003-07-04 13:52) [12]
> У тебя комовский как раз st и является
Нет, st - это поток, созданный из дискового файла filename1.
Мне нужно в коме создать файл из этого потока с именем filename2.
Оператор TDMP.PutFile(filename2, st); создает его, но через пару минут атрибуты файла слетают, хотя сам файл в коме остается ...
← →
Serginio (2003-07-04 13:56) [13]Тогда атрибуты какого файла слетают????
← →
avkiev (2003-07-04 14:01) [14]Того, который в коме.
Думается, это из-за того, что я не уничтожаю st ...
← →
avkiev (2003-07-04 14:07) [15]Может, Commit какой-нить применить ...
← →
Serginio (2003-07-04 14:26) [16]St у тебя при выходе из процедуры уничтожается (область видимости). Ну смотри куда сохраняешь. Если работаешь с IStorage смотри темы недавно были.
← →
avkiev (2003-07-04 15:06) [17]Давай вернемся к началу.
В type libraty com-объекта есть такая процедура:
procedure TDMP.PutFile(const path: WideString; const content: IUnknown);
begin
DefaultInterface.PutFile(path, content);
end;
Нужно с помощью этой процедуры скопировать файл filename1 с диска в ком под именем filename2.
Я это делаю так:
var st: IStream;
f: TFileStream;
...
f := TFileStream.Create(filename1, fmOpenRead);
st := TStreamAdapter.Create(f, soOwned) as IStream;
TDMP.PutFile(filename2, st);
f.Free;
Файл создается, его содержимое копируется с диска, ему устанавливаются верные атрибуты.
Но через 20 секунд после вызова процедуры TDMP.PutFile время/дата файла слетают в 0.
Блин, что делать ???
← →
Serginio (2003-07-04 15:12) [18]Это код я уже видел. Интересно знать хотя бы суть. Только гадать приходится.
Тоесть TDMP.PutFile создает физически файл filename2 ??? Так может он ему и не нужен.
И вообще что это за TDMP. Почему TMD а не экземпляр класаа (DMP:=TDMP.Create)
← →
avkiev (2003-07-04 15:20) [19]TDMP-класс, описывающий мобильный телефон, как устройство хранения информации ( типа винчестер :) ).
Файл реально создается в телефоне.
Да, это я неправильно написал, конечно же у меня в программе DMP.PutFile, где DMP:=TDMP.Create
← →
Serginio (2003-07-04 15:33) [20]Тогда разберись с этим СОМ классом. Здесь я бессилен.
Да если ты применяешь st := TStreamAdapter.Create(f, soOwned)
то F.Free не нужен. Смотри Serginio (03.07.03 18:51)
← →
avkiev (2003-07-04 15:35) [21]Спасибо и на этом, буду ковыряться
← →
avkiev (2003-07-04 16:43) [22]Вот что вычитал в документации к функции TStreamAdapter.Stat:
Stat sets all of the TFileTime parameters to 0.
Это как раз то, что происходит в моем случае.
Вопрос такой: как после создания файла с помощью функции PutFile "отцепить" его от переменной st чтобы жизнь и поведение этого файла никак не зависела от st ?
← →
Serginio (2003-07-04 16:51) [23]Можешь создать свой класс TStreamAdapter переопределть функцию, если FStrea is FileStream. Все в твоих руках.
function TStreamAdapter.Stat(out statstg: TStatStg; grfStatFlag: Longint): HResult;
begin
Result := S_OK;
try
if (@statstg <> nil) then
with statstg do
begin
dwType := STGTY_STREAM;
cbSize := FStream.Size;
mTime.dwLowDateTime := 0;
mTime.dwHighDateTime := 0;
cTime.dwLowDateTime := 0;
cTime.dwHighDateTime := 0;
aTime.dwLowDateTime := 0;
aTime.dwHighDateTime := 0;
grfLocksSupported := LOCK_WRITE;
end;
except
Result := E_UNEXPECTED;
end;
end;
← →
avkiev (2003-07-04 16:53) [24]Или как изменять поля mtime, ctime, atime записи, возвращаемой функцией TStreamAdapter.Stat ?
← →
avkiev (2003-07-04 16:55) [25]Не видел твой ответ, спасибо, попробую
← →
Serginio (2003-07-04 17:00) [26]Учти, что в качестве FStream может выступать TMemoryStream. Записывай текущее время.
Страницы: 1 вся ветка
Текущий архив: 2003.07.17;
Скачать: CL | DM;
Память: 0.5 MB
Время: 0.009 c