Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.53 MB
Время: 0.016 c
4-55885
Алексей
2003-05-15 07:42
2003.07.17
Как прочитать информацию из текстового файла


14-55774
rosa_t
2003-06-30 12:57
2003.07.17
помогите с тестированием объектно-ориентированной программы


1-55630
Immortal_Death
2003-07-03 12:02
2003.07.17
Уникальнное имя компонента...


14-55800
miek
2003-07-01 00:14
2003.07.17
Борландовский юмор


14-55717
AstaLabista
2003-07-01 05:43
2003.07.17
где отрыть исходник нюка