Stream class that stores binary data in files.
For example, the following code opens a file binary stream, points it at a particular file
on the filesystem, and then reads it in chunks of 32,000 bytes:
Set stream=##class(%Stream.FileBinary).%New()
Set sc=stream.LinkToFile("c:\myfile.txt")
While 'stream.AtEnd {
Set line=stream.Read()
; Process the chunk here
}
property Filename as %String (MAXLEN = 5000) [ Calculated ];
The filename that this stream is currently using
If you set this property to update the file we will write to/read from
this operation can fail if for example the directory specified does not exist.
To detect this failure either check the %Status return code of the FilenameSet()
or if using 'Set stream.Filename=newname' then check %objlasterror after the call to see if it
reported an error.
For file streams the line will terminate on any of the characters set in the LineTerminator, it does not support
multi-character line terminators because it uses the ObjectScript file behavior which terminates on any of the characters.
Also for %FileCharacterStream even if you set this when you call WriteLine() as the file was opened in 'S'
mode it will normalize the line terminator as the data is being written, so for example if you set LineTerminator to
$char(13,10) on Unix systems when you call WriteLine() it will only write $char(10) to the file.
If true then remove the permanent file as well as any temp file when this object is closed.
If you call %Save on a stream where RemoveOnClose is true it will set this to false as if you
explicitly save the stream you no longer want it to be removed when the object is closed. In order
to make sure %Save always runs the logic to reset the flag setting this to true
causes %IsModified/%ObjectModified to return true.
Inherited description: Returns true (1) if a property of this instance has been modified, otherwise false (0).
A TRUE result does not necessarily mean that any property has actually been changed. If
%IsModified() returns false then the object has not been modified. There are some
situations where we simply cannot efficiently detect a change in value. In these cases we
will set the modified status of the property.
Inherited description: Returns true if this is a "NULL" stream; that is, a stream which has never
been written to and saved and has no stream attributes. This is used by the InterSystems IRIS ODBC server.
Note that setting the %Location will cause a few things to happen.
It will delete any temporary file that may have been created. It will not touch any
permanent file that this object was associated with, if you wish to delete this pre-existing
permanent file then call Clear() passing '1' as the argument before setting
the %Location. It then marks this object as pointing to a null stream in the new directory
you specified.
Inherited description: Normalizes all of an object's property values by invoking the data type Normalize methods.
Many data types may allow many different representations of the same value.
Normalization converts a value to its cannonical, or normalized, form.
Inherited description: This method is somewhat similar to %IsModified but it also checks to see if swizzled
references would cause the object to become modified should they be serialized. This works
on the assumption that a reference to a persistent object will never be modified if the ID has
already been assigned. For references to serial objects, a call to %ObjectModified indicates
whether or not the serialized value is different. If the reference to a swizzled object is
different from the initial object state then the $$$objModAll macro will already return true.
Reference the Set code.
Returns true (1) if this instance has been modified, otherwise false (0).
The %Save() method of a persistent class calls this method before filing any objects in the database. The
%ValidateObject() of a referencing object can call it. You can also call it explicitly at any time.
It checks if any required property values are missing.
If the PROPERTYVALIDATION class parameter is set to ValidateOnSave, it validates each non-null property value by calling the
property method IsValid on each literal property and the %ValidateObject method for each object-valued embedded object
property (properties whose type extend %SerialObject).
If checkserial is 1, it forces the checking of any embedded object properties by calling their %ValidateObject method after
swizzling this property.
If checkserial is 2, it forces the checking of any collections of serial types by iterating over those collections and calling their
%ValidateObject() method after swizzling this property, in addition to the validation that occurs when checkserial is 1.
%ValidateObject() returns a %Status indicating success or error. It is up to the caller to process the error value.
%ValidateObject() does not validate object-valued reference properties (properties whose type extends %Persistent) due to the possibility
of circular dependencies between objects. The %Save() method of a persistent class automatically detects and handles circular references
between objects. If you require the validation of reference properties, you can override this method in a subclass or call %Save() directly.
Inherited description: Clear the contents of this Stream from permanent storage. This will remove the permanent stream storage and
any temporary stream and initialise the stream to its initial state that it starts in, including removing all
the stream attributes.
Returns a %Status value indicating success or failure.
This method lets you connect a file stream to a file called filename without
making a copy of it. If the file does not already exist it will still allow you to link
to this file, and %IsNull() will return true until you write to this file.
Do object.Image.LinkToFile("\temp\image.jpg")
Do object.%Save()
The method as its name suggests creates a LINK to an EXISTING
file. So this is a 'shared public' file, as it can be shared by
several instances of a class, or even several classes.
Using the CopyFrom() method, on the contrary, creates a
'private' image, not sharable by other instances/classes, so
these two methods are really different.
The problems with shared public images are that several instances
are all allowed to update and even delete the image, causing
problems for other instances.
For example, if dog #2 has image 'test.gif', I can also
assign that image to dog #5 or even person #24
If I change the image for dog #5, then the image is changed in
place to another image, thus upsetting dog#2 and person#24.
If I delete dog#5, the image is also deleted and thus dog#2
and person#24 are changed.
Also note that if there is currently some temporary data in the old stream when the
LinkToFile() is called this temporary data will be removed before the
stream is linked to this filename.
Move to this position in the stream. If this suceeds then return
true, else return false.
Note that moving to position 1 will be at the start of the stream, position 2 will be
at the second character of the stream, etc.
Inherited description: Move to the end of the stream so the next Write will be appended to the end.
This allows you to read from a stream, then MoveToEnd() and append new data, where just calling
Write() after a read will clear the stream before writing new data.
Returns a %Status value indicating success or failure.
method OutputToDevice(ByRef len As %Integer = -1) as %Status
Inherited description: Write out len characters of the stream to the current device starting from the current position. This
method is optimised for performance by the various sub classes. If len is omitted or set to -1 then
it will write out the entire stream starting at the beginning.
Inherited description: Reads up to len characters from the current position
in the stream. The current position is advanced by the number of
characters read. Upon exit, len is set to the actual
number of characters read. If a read occurs when the stream position
is at the end of the stream, len will be set to -1 and
Read() will return a null string (""). If no len
is passed in, ie. 'Read()()' then it is up to the Read implementation as to
how much data to return. Some stream classes use this to optimize the amount of
data returned to align this with the underlying storage of the stream.
You must call Rewind() if you want to read a stream from the beginning
again. Calling Read() after Write() implicitly ends the Write()
operation and rewinds to the start of the stream.
Returns a string up to len characters long. The byref argument sc will
return a %Status if any error occurred during the read.
Read a line from the file. Note that besides the normal ReadLine arguments this can also be passed a term which
will return the terminator that completed the line if we read in a whole line.
Appends the string data along with a line terminator to the stream and advances the
current stream position by the number of characters in data plus the line terminator.
Returns a %Status value indicating success or failure.