import ballerina/io;
function getFileChannel (string filePath, string permission) returns (io:ByteChannel) {
    io:ByteChannel channel = io:openFile(filePath, permission);
    return channel;
}
function readBytes (io:ByteChannel channel, int numberOfBytes) returns (blob, int) {
    var result = channel.read(numberOfBytes);
    match result {
        (blob, int) content => {
            return content;
            }
        io:IOError readError => {
            throw readError;
            }
       }
}
function writeBytes (io:ByteChannel channel, blob content, int startOffset = 0) returns (int) {
    var result = channel.write(content,startOffset);
    match result {
        int numberOfBytesWritten => {
            return numberOfBytesWritten;
          }
       io:IOError err => {
          throw err;
           }
    }
}
function copy (io:ByteChannel src, io:ByteChannel dst) {
    int bytesChunk = 10000;
    int numberOfBytesWritten = 0;
    int readCount = 0;
    int offset = 0;
    blob readContent;
    boolean doneCoping = false;
    try {
        while (!doneCoping) {
        (readContent, readCount) = readBytes(src,1000);
            if (readCount <= 0) {
                doneCoping = true;
            }
            numberOfBytesWritten = writeBytes(dst, readContent);
        }
    } catch (error err) {
        throw err;
    }
}function main (string[] args) {
    string srcFilePath = "./files/ballerina.jpg";
    string dstFilePath = "./files/ballerinaCopy.jpg";
    io:ByteChannel sourceChannel = getFileChannel(srcFilePath, "r");
    io:ByteChannel destinationChannel = getFileChannel(dstFilePath, "w");
    try {
        io:println("Start to copy files from " + srcFilePath + " to " + dstFilePath);
        copy(sourceChannel, destinationChannel);
        io:println("File copy completed. The copied file could be located in " + dstFilePath);
    }catch (error err) {
        io:println("error occurred while performing copy " + err.message);
    }finally {
        _ = sourceChannel.close();
        _ = destinationChannel.close();
    }
}

Byte I/O

This example demonstrates how bytes can be read and written through the I/O API.

import ballerina/io;
function getFileChannel (string filePath, string permission) returns (io:ByteChannel) {

This function returns a ByteChannel from a given file location according to the specified file permission (i.e., whether the file should be opened for read or write).

    io:ByteChannel channel = io:openFile(filePath, permission);
    return channel;
}

Here is how the ByteChannel is retrieved from the file.

function readBytes (io:ByteChannel channel, int numberOfBytes) returns (blob, int) {

This function reads a specified number of bytes from the given channel.

    var result = channel.read(numberOfBytes);
    match result {
        (blob, int) content => {
            return content;
            }
        io:IOError readError => {
            throw readError;
            }
       }
}

Here is how the bytes are read from the channel.

function writeBytes (io:ByteChannel channel, blob content, int startOffset = 0) returns (int) {

This function writes a byte content with the given offset to a channel.

    var result = channel.write(content,startOffset);
    match result {
        int numberOfBytesWritten => {
            return numberOfBytesWritten;
          }
       io:IOError err => {
          throw err;
           }
    }
}

Here is how the bytes are written to the channel.

function copy (io:ByteChannel src, io:ByteChannel dst) {

This function copies content from the source channel to a destination channel.

    int bytesChunk = 10000;
    int numberOfBytesWritten = 0;
    int readCount = 0;
    int offset = 0;
    blob readContent;
    boolean doneCoping = false;
    try {

Specifies the number of bytes that should be read from a single read operation.

        while (!doneCoping) {
        (readContent, readCount) = readBytes(src,1000);
            if (readCount <= 0) {

Here is how to read all the content from the source and copy it to the destination.

                doneCoping = true;
            }
            numberOfBytesWritten = writeBytes(dst, readContent);
        }
    } catch (error err) {
        throw err;
    }
}

If no content is read, the loop is ended.

function main (string[] args) {
    string srcFilePath = "./files/ballerina.jpg";
    string dstFilePath = "./files/ballerinaCopy.jpg";
    io:ByteChannel sourceChannel = getFileChannel(srcFilePath, "r");
    io:ByteChannel destinationChannel = getFileChannel(dstFilePath, "w");
    try {
        io:println("Start to copy files from " + srcFilePath + " to " + dstFilePath);
        copy(sourceChannel, destinationChannel);
        io:println("File copy completed. The copied file could be located in " + dstFilePath);
    }catch (error err) {
        io:println("error occurred while performing copy " + err.message);
    }finally {

Read the specified number of bytes from the given channel and write.

        _ = sourceChannel.close();
        _ = destinationChannel.close();
    }
}

Close the created connections.

$ ballerina run byte-i-o.bal
Start to copy files from ./files/ballerina.jpg to ./files/ballerinaCopy.jpg
File copy completed. The copied file could be located in ./files/ballerinaCopy.jpg