Solved

Destroying TMemoryStream

Posted on 2002-06-19
13
351 Views
Last Modified: 2010-04-04
I have BLOB field where I store documents from OleContainer (streams). Later on, I can use OleContainer to open and modify document. How I do that:
1. Declare str:TMemoryStream on the Form level
2. On btnOpenClick I create str:TMemoryStream, read the value from BLOB field, put it in OleContainer as stream, open Ole (DoVerb) object, modify it and update OleContainer.
3.Then on btnSaveClick, I use the same stream "str" (created in another procedure but declared on form-level) to update Blob field.

Question/Problem: I noticed that if I try to destroy the "str" (str.Free) after calling myAdoDataSet.Post, it will not post the changes and I got error "dataset not in edit or insert mode". But, if I don't Free the stream then it's fine. ??? Why? Is it safe to do this way, will my "str" object be Killed when I close the form?

Here is the "save to database" code:

begin
if (rst.State=dsEdit) then
begin
str.Clear;

ole1.SaveToStream(str);
rst.Edit;
TBlobField(rst.FieldByName('Document')).LoadFromStream(str);
showmessage(inttostr(str.size));
rst.Post;
//if assigned(str) then str.Free;
end;
rst.Close;
ole1.DestroyObject;
end;
0
Comment
Question by:bogiboy
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 5
  • 3
13 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 7093476
? mysterious ... listening . . .
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7094422
yous should try rst.FlushBuffers; that writes data to disk


I never liked .FieldByName
it searches through all the fields to find the proper one
I rather use desingtime field creation
doubleclick the dataset and Add new fields
so you get a new object like : rstBlobField: TBlobField;

then you simply use rstBlobField.LoadFromStream(str);
that has always worked for me
and this was also a solution for one of the questions on EE
the coder used the same method as you and had similar problems
with my method it worked :)
try it out
0
 
LVL 1

Author Comment

by:bogiboy
ID: 7096955
Strange, strange, strange...
Instead of rst.Free I tried with rst:=nil and IT WORKS!?
Hm...Why?
BTW, I use ADO so FlushBuffers is not applicable..
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:bogiboy
ID: 7096964
Sorry, I made mistake, it was not rst:=nil but str:=nil...So if I dispose stream using str:=nil, I don't get an error...
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7097193
that way you don't free it's memory !
you simply set the str reference to nil
the actual stream is still in memory
try my suggestion
0
 
LVL 1

Author Comment

by:bogiboy
ID: 7097372
No, no, I tried your suggestion and created persistent fields, but still doesn't work- error is poping up "dataset not in insert or edit mode". What you are saying is that if I use myStream:=nil it will be still in the memory? Will it be destroyed when I dereference form where it is declared?
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 7097409
>it will be still in the memory?
yes

>Will it be destroyed when I dereference form where it is declared?
no, only free or destroy does this job (free is the reommended method)

meikl ;-)
0
 
LVL 1

Author Comment

by:bogiboy
ID: 7097543
I am confused now with this:

...
if assigned(str) then
begin
str:=nil;
str.Free;
end;
...
and I am not getting error now??? And my document in DB is updated! Opinions?
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7097863
:)

first you set it's reference to nil
then you try to free it
but .Free check if the object is nil
if it's nil then it does nothing !!!

about my method .. did you do :

// load the ole into str
rst.Edit;
rstBlobField.LoadFromStream(str);
rst.Post;
FreeAndNil(str);
0
 
LVL 1

Author Comment

by:bogiboy
ID: 7099338
No Lee, I created persistent fields ("Add all fields...") and did exactly as you suggested- and still nothing.
Speaking of nil and Free:
In help, i found that Free is a safe way do destroy objects because Destroy doesn't check if object is nil - Free does. But it also says that for Free it doesnt't matter if object is nil or not, it will destroy it. Did I misunderstood this paragraph?

From Help>TObject>Free:

"Use Free to destroy an object. Free automatically calls the destructor if the object reference is not nil. Any object instantiated at runtime that does not have an owner should be destroyed by a call to Free so that it can be properly disposed of and its memory released. Unlike Destroy, Free is successful even if the object is nil; so if the object was never initialized, Free won’t result in an error."
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 7099362
>Free automatically calls the destructor if the object reference is not nil

the destructor is never called, if u use this
str:=nil;
str.Free;
the object still remains in memory
and you have lost its reference

still cannot reproduce your problem

meikl ;-)
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 7099366
>> Unlike Destroy, Free is successful even if the object is nil; so if the object was never initialized, Free won’t result in an error.

it's merely saying that free will always work - meaning it will not produce an error if the object is nil as destroy would

well you might think of a global stream :)
create when the form is created and free when the form is destroyed
0
 
LVL 12

Accepted Solution

by:
Lee_Nover earned 30 total points
ID: 7099371

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;

there :)
(borland might hate me for this getting out to those Delphi PE users :)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

737 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question