1. %Stream for file I/O
Key Points
- %Stream.FileCharacter: Read/write text files with character encoding support
- %Stream.FileBinary: Read/write binary files (images, PDFs, etc.)
- .Filename property: Set the file path before reading or writing
- .Write() / .WriteLine(): Write content to the stream
- .Read(len): Read up to len characters/bytes from the stream
- .ReadLine(): Read one line of text (for character streams)
- .Rewind(): Reset position to beginning of stream
- .MoveToEnd(): Position at end of stream (for appending)
- .AtEnd: Property that is true when no more data to read
- .Size: Property containing the total size of the stream
Detailed Notes
Overview
The %Stream classes provide ObjectScript's standard file I/O mechanism. Unlike traditional languages that use file handles, InterSystems IRIS uses stream objects that encapsulate the file, its position, and its encoding. Streams are also used extensively in web services, SQL BLOBs/CLOBs, and interoperability productions.
Writing a Text File
SET stream = ##class(%Stream.FileCharacter).%New()
SET stream.Filename = "/tmp/output.txt"
// Write content
DO stream.WriteLine("Line 1: Hello World")
DO stream.WriteLine("Line 2: ObjectScript")
DO stream.Write("No newline at end")
// Save the stream to disk
SET status = stream.%Save()
IF $$$ISERR(status) {
WRITE "Error saving: ", $SYSTEM.Status.GetErrorText(status), !
} ELSE {
WRITE "File written successfully", !
}
Reading a Text File
SET stream = ##class(%Stream.FileCharacter).%New()
SET stream.Filename = "/tmp/output.txt"
// Check if file exists via Size
IF stream.Size = 0 {
WRITE "File is empty or does not exist", !
QUIT
}
// Read line by line
WHILE 'stream.AtEnd {
SET line = stream.ReadLine()
WRITE line, !
}
Reading a Fixed Number of Characters
SET stream = ##class(%Stream.FileCharacter).%New()
SET stream.Filename = "/tmp/largefile.txt"
// Read in chunks of 32000 characters
WHILE 'stream.AtEnd {
SET chunk = stream.Read(32000)
// Process chunk...
SET totalLen = totalLen + $LENGTH(chunk)
}
WRITE "Total characters read: ", totalLen, !
Binary File Operations
// Copy a binary file
SET input = ##class(%Stream.FileBinary).%New()
SET input.Filename = "/tmp/image.png"
SET output = ##class(%Stream.FileBinary).%New()
SET output.Filename = "/tmp/image_copy.png"
// Copy content
WHILE 'input.AtEnd {
SET chunk = input.Read(32000)
DO output.Write(chunk)
}
SET status = output.%Save()
Stream Navigation
SET stream = ##class(%Stream.FileCharacter).%New()
SET stream.Filename = "/tmp/data.txt"
// Read first line
SET firstLine = stream.ReadLine()
WRITE "First: ", firstLine, !
// Rewind to beginning
DO stream.Rewind()
// Read everything
SET all = stream.Read(stream.Size)
// Move to end for appending
DO stream.MoveToEnd()
DO stream.WriteLine("Appended line")
SET status = stream.%Save()
Copying Between Streams
// CopyFrom copies one stream's content into another
SET source = ##class(%Stream.FileCharacter).%New()
SET source.Filename = "/tmp/source.txt"
SET dest = ##class(%Stream.FileCharacter).%New()
SET dest.Filename = "/tmp/dest.txt"
SET status = dest.CopyFrom(source)
SET status = dest.%Save()
Stream Properties and Methods Summary
SET stream = ##class(%Stream.FileCharacter).%New()
SET stream.Filename = "/tmp/test.txt"
// Properties
WRITE "Size: ", stream.Size, ! // Total size in characters/bytes
WRITE "At End: ", stream.AtEnd, ! // 1 if position is at end
WRITE "Filename: ", stream.Filename, ! // File path
// Key Methods
// stream.Read(len) - Read up to len chars
// stream.ReadLine() - Read one line (text streams)
// stream.Write(data) - Write data
// stream.WriteLine(data) - Write data + newline
// stream.Rewind() - Go to beginning
// stream.MoveToEnd() - Go to end
// stream.CopyFrom(src) - Copy from another stream
// stream.Clear() - Remove all content
// stream.%Save() - Persist changes to disk
Documentation References
2. %Net for HTTP, FTP, and email
Key Points
- %Net.HttpRequest: Send HTTP GET, POST, PUT, DELETE requests
- %Net.HttpResponse: Response object with StatusCode, Data (stream), headers
- %Net.FtpSession: Connect to FTP servers, upload/download files
- %Net.SMTP: Send email messages via SMTP
- %Net.MailMessage: Compose email messages with attachments
- SSL/TLS: Configure via SSLConfiguration property for HTTPS connections
- Timeout: Set timeouts to avoid blocking on unresponsive servers
Detailed Notes
Overview
The %Net package provides classes for common network protocols. %Net.HttpRequest handles HTTP communication (REST APIs, web services), %Net.FtpSession manages FTP file transfers, and %Net.SMTP sends email. These classes are essential for integrating InterSystems IRIS with external systems.
HTTP GET Request
SET request = ##class(%Net.HttpRequest).%New()
SET request.Server = "api.example.com"
SET request.Port = 443
SET request.Https = 1
SET request.SSLConfiguration = "MySSLConfig"
SET request.Timeout = 30
// Send GET request
SET status = request.Get("/api/users/1")
IF $$$ISERR(status) {
WRITE "Request failed: ", $SYSTEM.Status.GetErrorText(status), !
QUIT
}
// Read response
SET response = request.HttpResponse
WRITE "Status: ", response.StatusCode, !
WRITE "Content-Type: ", response.GetHeader("Content-Type"), !
// Read response body
SET body = ""
WHILE 'response.Data.AtEnd {
SET body = body _ response.Data.Read(32000)
}
WRITE "Body: ", body, !
HTTP POST Request with JSON
SET request = ##class(%Net.HttpRequest).%New()
SET request.Server = "api.example.com"
SET request.ContentType = "application/json"
// Build JSON body using %DynamicObject
SET json = {}
SET json.name = "Alice"
SET json.age = 30
SET json.city = "New York"
// Write JSON to request body
DO request.EntityBody.Write(json.%ToJSON())
// Send POST
SET status = request.Post("/api/users")
IF $$$ISOK(status) {
WRITE "Created! Status: ", request.HttpResponse.StatusCode, !
}
HTTP with Custom Headers
SET request = ##class(%Net.HttpRequest).%New()
SET request.Server = "api.example.com"
// Set custom headers
DO request.SetHeader("Authorization", "Bearer " _ token)
DO request.SetHeader("Accept", "application/json")
DO request.SetHeader("X-Custom-Header", "value")
SET status = request.Get("/api/protected-resource")
HTTP Response Handling
// Check status codes
SET response = request.HttpResponse
IF response.StatusCode = 200 {
// Parse JSON response
SET jsonStr = response.Data.Read(response.Data.Size)
SET obj = {}.%FromJSON(jsonStr)
WRITE "Name: ", obj.name, !
} ELSEIF response.StatusCode = 404 {
WRITE "Not found", !
} ELSEIF response.StatusCode >= 500 {
WRITE "Server error: ", response.StatusCode, !
}
FTP Operations
SET ftp = ##class(%Net.FtpSession).%New()
SET ftp.Server = "ftp.example.com"
SET ftp.Username = "user"
SET ftp.Password = "pass"
// Connect
SET status = ftp.Connect()
IF $$$ISERR(status) {
WRITE "FTP connect failed", !
QUIT
}
// Change directory
DO ftp.SetDirectory("/uploads")
// Upload a file
SET stream = ##class(%Stream.FileBinary).%New()
SET stream.Filename = "/tmp/upload.txt"
SET status = ftp.Store("remote_file.txt", stream)
// Download a file
SET download = ##class(%Stream.FileBinary).%New()
SET download.Filename = "/tmp/downloaded.txt"
SET status = ftp.Retrieve("remote_file.txt", .download)
DO download.%Save()
// List directory
SET status = ftp.List(.list)
// Disconnect
DO ftp.Logout()
Sending Email via SMTP
// Create the email message
SET msg = ##class(%Net.MailMessage).%New()
SET msg.From = "sender@example.com"
DO msg.To.Insert("recipient@example.com")
DO msg.Cc.Insert("cc@example.com")
SET msg.Subject = "Test Email from IRIS"
SET msg.IsSent = 0
SET msg.IsHTML = 1
// HTML body
DO msg.TextData.Write("<h1>Hello!</h1>")
DO msg.TextData.Write("<p>This email was sent from InterSystems IRIS.</p>")
// Add attachment
SET status = msg.AttachFile("/tmp", "report.pdf")
// Configure and send via SMTP
SET smtp = ##class(%Net.SMTP).%New()
SET smtp.smtpserver = "smtp.example.com"
SET smtp.port = 587
SET smtp.timezone = "US/Eastern"
// Authentication
SET auth = ##class(%Net.Authenticator).%New()
SET auth.UserName = "user@example.com"
SET auth.Password = "password"
SET smtp.authenticator = auth
// Send
SET status = smtp.Send(msg)
IF $$$ISOK(status) {
WRITE "Email sent successfully", !
} ELSE {
WRITE "Failed: ", $SYSTEM.Status.GetErrorText(status), !
}
Plain Text Email
SET msg = ##class(%Net.MailMessage).%New()
SET msg.From = "noreply@example.com"
DO msg.To.Insert("admin@example.com")
SET msg.Subject = "Alert: System Notification"
SET msg.IsHTML = 0
// Plain text body
DO msg.TextData.Write("This is a plain text alert.")
DO msg.TextData.Write($CHAR(13, 10)) // CRLF
DO msg.TextData.Write("Please check the system.")
SET smtp = ##class(%Net.SMTP).%New()
SET smtp.smtpserver = "smtp.example.com"
SET status = smtp.Send(msg)
Documentation References
Exam Preparation Summary
Critical Concepts to Master:
- %Stream.FileCharacter vs %Stream.FileBinary: Character streams for text, binary for everything else
- Stream reading pattern: WHILE 'stream.AtEnd { SET data = stream.Read(len) }
- Stream writing: .Write() for raw content, .WriteLine() adds newline, .%Save() persists to disk
- Stream navigation: .Rewind() to start, .MoveToEnd() for appending, .AtEnd to check for more data
- %Net.HttpRequest flow: Create -> Set Server/Port -> Set Headers -> Get/Post -> Read HttpResponse
- Response body is a stream: request.HttpResponse.Data is a %Stream -- read it like any stream
- SMTP sending: Create %Net.MailMessage -> Configure %Net.SMTP -> smtp.Send(msg)
- FTP flow: Create %Net.FtpSession -> Connect -> Store/Retrieve -> Logout
- SSL configuration: Set SSLConfiguration property for HTTPS; requires pre-configured SSL config in IRIS
- Error handling: Always check %Status return values from network operations
Common Exam Scenarios:
- Writing code to read a text file line by line using %Stream.FileCharacter
- Sending an HTTP GET request and processing the JSON response
- Choosing between FileCharacter and FileBinary for a given file type
- Configuring an HTTP POST request with JSON body and custom headers
- Sending an email with an attachment using %Net.SMTP and %Net.MailMessage
- Reading an HTTP response body from the Data stream property
- Handling stream operations: Rewind, Read, AtEnd, MoveToEnd
- Setting up FTP file transfer with %Net.FtpSession
Hands-On Practice Recommendations:
- Write a text file, then read it back line by line using %Stream.FileCharacter
- Copy a binary file using %Stream.FileBinary with chunked reads
- Send HTTP GET requests to a public API and parse JSON responses
- Send HTTP POST requests with JSON bodies
- Set up a simple SMTP test to send email (use a test SMTP server)
- Practice stream navigation: write, rewind, read, move to end, append
- Use CopyFrom to copy content between streams
- Experiment with HTTP response status codes and headers