Module : io
Module Overview
This module is designed to support input and output operations via channels in a canonical way, either in a blocking, or non-blocking manner.
Channels
A channel represents an I/O source or sink of some bytes, characters, or records that are opened for reading, or writing, respectively.
Byte channels
The most primitive channel is the ByteChannel
which reads and writes 8-bit bytes.
// Open a file in read mode.
io:ReadableByteChannel readableByteChannel = io:openReadableFile("some/file.txt");
// Here is how 100 bytes are read from the channel.
(byte[], int)|error result = readableByteChannel.read(100);
// Open a file in write mode.
io:WritableByteChannel writableByteChannel = io:openWritableFile("some/file.txt");
// Write some content to the beginning of the file.
string someContent = "some content";
byte[] content = someContent.toByteArray("UTF-8");
int|error result = writableByteChannel.write(content, 0);
Character channels
The CharacterChannel
is used to read and write characters. The charset encoding is specified when creating the
CharacterChannel
.
// Create a `ReadableCharacterChannel` from the `ReadableByteChannel`.
var readableCharChannel = new io:ReadableCharacterChannel(readableByteChannel, "UTF-8");
If a ReadableCharacterChannel
points to a JSON or XML source, it can be read and then written, directly into a variable of
the respective type.
// Reading a JSON.
json|error result = readableCharChannel.readJson();
// Reading an XML.
var result = readableCharChannel.readXml();
// Create a `WritableCharacterChannel` from the `WritableByteChannel`.
var writableCharChannel = new io:WritableCharacterChannel(writableByteChannel, "UTF-8");
// Writing a JSON.
json content = {fname:"Jhon", lname:"Doe", age:40};
var writeResult = writableCharChannel.writeJson(content);
if (writeResult is error) {
return writeResult;
} else {
io:println("JSON content written successfully.");
}
Record channels
Ballerina also supports I/O for delimited records.
// Create a `ReadableTextRecordChannel` from the `ReadableCharacterChannel`.
// Records are separated using a new line, and fields of a record are separated using a comma.
var readableRecordsChannel = new io:ReadableTextRecordChannel(readableCharChannel, fs = ",", rs = "\n");
// Read few records.
while (readableRecordsChannel.hasNext()) {
var result = readableRecordsChannel.getNext();
if (result is string[]) {
io:println(result); // Retrieved a record.
} else {
return result; // An IO error occurred when reading the records.
}
}
A .CSV
file can be read and written directly into a CSVChannel
, as shown in this code snippet.
// Create a `ReadableCSVChannel` from the `ReadableCharacterChannel`.
var readableCSVChannel = new io:ReadableCSVChannel(readableCharChannel);
Records of the .CSV
file can read directly into a table of a matching type.
// First let’s define a type that matches a record in the CSV file.
type Employee record {
string id;
string name;
float salary;
};
// Now read the CSV file as a table of Employees and compute total salary.
float total = 0.0;
var tableResult = csv.getTable(Employee);
if (tableResult is table<Employee>) {
foreach var x in tableResult {
total = total + x.salary;
}
return total;
} else if (tableResult is error) {
return tableResult; //Return the error back to the caller
} else {
error e = error(IO_ERROR_CODE, { message : "Record channel not initialized properly" });
return e;
}
Data Channels
Ballerina supports performing data i/o operations
Person object could be serialized into a file or a network socket in the following manner.
public type Person record {
string name;
int age;
float income;
boolean isMarried;
};
// Serialize record into binary.
function serialize(Person p, io:WritableByteChannel byteChannel) {
io:WritableDataChannel dc = new io:WritableDataChannel(byteChannel);
var length = p.name.toByteArray("UTF-8").length();
var lengthResult = dc.writeInt32(length);
var nameResult = dc.writeString(p.name, "UTF-8");
var ageResult = dc.writeInt16(p.age);
var incomeResult = dc.writeFloat64(p.income);
var maritalStatusResult = dc.writeBool(p.isMarried);
var closeResult = dc.close();
}
// Deserialize record into binary.
function deserialize(io:ReadableByteChannel byteChannel) returns Person {
Person person = {};
int nameLength = 0;
string nameValue;
io:ReadableDataChannel dc = new io:ReadableDataChannel(byteChannel);
// Read 32 bit signed integer.
var int32Result = dc.readInt32();
if (int32Result is int) {
nameLength = int32Result;
} else if (int32Result is error) {
log:printError("Error occurred while reading name length", err = int32Result);
}
// Read UTF-8 encoded string represented through specified amount of bytes.
var strResult = dc.readString(nameLength, "UTF-8");
if (strResult is string) {
person.name = strResult;
} else if (strResult is error) {
log:printError("Error occurred while reading name", err = strResult);
}
// Read 16 bit signed integer.
var int16Result = dc.readInt16();
if (int16Result is int) {
person.age = int16Result;
} else if (int16Result is error) {
log:printError("Error occurred while reading age", err = int16Result);
}
// Read 64 bit signed float.
var float64Result = dc.readFloat64();
if (float64Result is float) {
person.income = float64Result;
} else if (float64Result is error) {
log:printError("Error occurred while reading income", err = float64Result);
}
// Read boolean.
var boolResult = dc.readBool();
if (boolResult is boolean) {
person.isMarried = boolResult;
} else if (boolResult is error) {
log:printError("Error occurred while reading marital status", err = boolResult);
}
// Finally close the data channel.
var closeResult = dc.close();
return person;
}
ReadableByteChannel | ReadableByteChannel represents an input resource (i.e file, socket). which could be used to source bytes. |
ReadableCSVChannel | Represents a ReadableCSVChannel which could be used to read records from CSV file. |
ReadableCharacterChannel | Represents a channel which could be used to read characters through a given ReadableByteChannel. |
ReadableDataChannel | Represents a data channel for reading data. |
ReadableTextRecordChannel | Represents a channel which will allow to read |
StringReader | Represents a reader which will wrap string content as a channel. |
WritableByteChannel | WritableByteChannel represents an output resource (i.e file, socket). which could be used to sink bytes. |
WritableCSVChannel | Represents a WritableCSVChannel which could be used to write records from CSV file. |
WritableCharacterChannel | Represents a channel which could be used to write characters through a given WritableCharacterChannel. |
WritableDataChannel | Represents a WritableDataChannel for writing data. |
WritableTextRecordChannel | Represents a channel which will allow to write records through a given WritableCharacterChannel. |
createReadableChannel | Creates an in-memory channel which will reference stream of bytes. |
openReadableCsvFile | Retrieves a readable CSV channel from a give file path. |
openReadableFile | Retrieves a ReadableByteChannel from a given file path. |
openWritableCsvFile | Retrieves a writable CSV channel from a give file path. |
openWritableFile | Retrieves a WritableByteChannel from a given file path. |
Prints |
|
println | Prints |
readln | Returns the input read from STDIN. |
sprintf | Returns a formatted string using the specified format string and arguments. Following format specifiers are allowed. b boolean B boolean (ALL_CAPS) d int f float x hex X HEX (ALL_CAPS) s string (This specifier is applicable for any of the supported types in Ballerina. These values will be converted to their string representation.) |
DEFAULT | |
CSV | |
TDF | |
COMMA | |
TAB | |
COLON | |
IO_ERROR | |
READ | |
WRITE | |
RW | |
APPEND | |
CSV_RECORD_SEPARATOR | Represents record separator of the CSV file. |
FS_COLON | Represents colon separator which should be used to identify colon separated files. |
MINIMUM_HEADER_COUNT | Represents minimum number of headers which will be included in CSV. |
BIG_ENDIAN | |
LITTLE_ENDIAN |
Format | Format which will be used to represent the CSV. DEFAULT - Would default to the format specified by CSVChannel. Precedence will be given to field separator and record separator. CSV - Field separator would be "," and the record separator would be new line. TDF - Field separator will be tab and record separator will be new line. |
Mode | |
Separator | Field separators which are supported by DelimitedTextRecordChannel. |
IOError |