SuiteScript Example – Read File Line by Line

Just as we can write to a file line by line, we can also read line by line:

define(["N/file"], function (f) {

    /**
     * Custom module for executing N/file cookbook examples
     *
     * @NApiVersion 2.0
     * @NModuleScope SameAccount
     */
    var exports = {};

    function readFile(response) {
        var weatherFile = f.load({id: "SuiteScripts/weather.csv"});

        var weatherData = [];
        weatherFile.lines.iterator().each(function (line) {
            var w = line.value.split(",");
            weatherData.push({date: w[0], low: w[1], high: w[2]});
            return true;
        });

        response.write({output: JSON.stringify(weatherData)});
    }

    exports.readFile = readFile;
    return exports;
});

Load the File 

var weatherFile = f.load({id: "SuiteScripts/weather.csv"});

Here we load the same CSV file as we created in the previous example.

File.lines.iterator()

weatherFile.lines.iterator()

File instances provide us with a lines Iterator which we can use to walk the lines of a File one by one.

Iterate and process each line

weatherFile.lines.iterator().each(function (line) {
    var w = line.value.split(",");
    weatherData.push({date: w[0], low: w[1], high: w[2]});
    return true;
});

The Iterator provides an each() method which will loop through the lines, passing each line to the callback function
you provide.

var w = line.value.split(",");

The line passed in is an Object, and you can retrieve the contents of the line from its value property. Here we do
a naive split() on all commas as we assume none of our column values contain commas. We then reconstruct the Objects
we used initially when we defined WeatherData and push() the Object onto the weatherData Array.

Your callback function can return false to stop or true to continue, similar to the way the each() iterator works
on Search Results. Returning nothing is the same as returning false. If you find that your script is only processing
the first line of the file, I can almost guarantee it’s because you forgot to return true.

Note that the lines Iterator can only be used on Text or CSV file types, and each line can be no more than 10MB (still
a ludicrously high limit).

Why Stream?

It might not be immediately obvious why you would read a file this way. Why not get the entire contents and get to work?

Files can be large; extremely large. Loading the entire contents of a huge file would immediately consume the entire
memory limit for your script. Further, you are presumably going to do something interesting with each line of a CSV, and
almost anything interesting uses governance. Trying to process a massive file all at once is almost guaranteed to run
you into the governance limit for your script.

Instead, you can use this approach to process the file without pushing up against either of these limits, allowing you
to stop and check your governance threshold, store your progress for next time, and react accordingly.

You can also use this as a preparatory step to processing large files, chunking them out into smaller, more manageable
file sizes.

HTH

-EG

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

Related posts

January 7, 2021

Anything I wrote today about business would both feel and be inadequate. I simply can’t arrive at the words to express how I feel in this moment. So instead, here are a few helpful ...

Read More

December 20, 2020

2020 was a hundred swift kicks to the shorts and one giant kick in the ass. If you’ve lost people you love, if you’ve gotten sick or hurt, if you’ve lost your job, if ...

Read More

December 16, 2020

“I’ve been meaning to learn SuiteScript, but it’s hard to find the time …”“We’re slammed, and I just don’t have the time …”“I haven’t made the time …” All are variations of a theme ...

Read More

December 14, 2020

Last week we looked at mimicking the functionality of a REST endpoint with its own module (e.g. retrieving a User, or a list of Users, refreshing a token, etc). For complex integrations that rely on a large ...

Read More