Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Destroying TMemoryStream

Posted on 2002-06-19
13
Medium Priority
?
355 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
  • 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
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!

 
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 90 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

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…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
Suggested Courses

824 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