November 24, 2020

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

March 3, 2021

Does the physical location of a competent employee change the amount of value they can deliver for your organization? If it does, I’d be keen to hear your story. If it does not, why ...

Read More

March 2, 2021

Today a friend and former colleague of mine – who happens to now be in a development leadership role for a NetSuite partner – was lamenting the extreme difficulty of finding and hiring NetSuite ...

Read More

March 1, 2021

Software is never finished; clients are always changing and re-prioritizing. NetSuite is ever a moving target – always updating and evolving. Market forces are always shifting and shoving, forcing new demands on your business. ...

Read More