2

I'm really struggling to find documentation on how to read a text file into an array using OS X Automation with Javascript.

Here's what I have so far:

var app = Application.currentApplication(); 
app.includeStandardAdditions = true; 

var myFile = "/Users/Me/Dropbox/textfile.txt";
var openedFile = app.openForAccess(myfile, { writePermission: true });

var myText = openedFile.??

app.closeAccess(URLFile);

I copied most of this from the official Apple documentation. I'm finding it really difficult to find documentation anywhere online. For example, what are the arguments for openForAccess? There doesn't seem to be anything in any dictionary to describe that method.

Am I wasting my time with JXA?

Andy Cairns
  • 21
  • 1
  • 4
  • For application automation, AppleScript is the only supported option that works right and has documentation and community support. For other tasks, if you can use Python, Ruby, Swift, or other language that's actively maintained and has a healthy user community, then do so. JXA's been effectively unfixed and unsupported from the first day it shipped, so unsurprisingly failed to build any market share, culminating in the sacking of the Automation Product Manager and elimination of the Mac Automation team last year, so probably not a good long-term investment. – foo Feb 27 '17 at 16:30
  • JXA is a very useful instrument. – houthakker May 19 '17 at 20:01

2 Answers2

1

Apple has an entire page devoted to reading and writing files in their Mac Automation Scripting Guide. This includes a function that performs exactly the action you are looking for. I've re-written your example below using the readAndSplitFile function from Apple's guide:

var app = Application.currentApplication()
app.includeStandardAdditions = true

function readAndSplitFile(file, delimiter) {
    // Convert the file to a string
    var fileString = file.toString()

    // Read the file using a specific delimiter and return the results
    return app.read(Path(fileString), { usingDelimiter: delimiter })
}

var fileContentsArray = readAndSplitFile('/Users/Me/Dropbox/textfile.txt', '\n')

After running the above code, fileContentsArray will hold an array of strings, with each string containg a single line of the file. (You could also use \t as a delimiter to break at every tab, or any other character of your choosing.)

aaplmath
  • 1,717
  • 1
  • 14
  • 27
1

Some generic functions and an illustrative test:

(function () {
    'use strict';

    // GENERIC FUNCTIONS ------------------------------------------------------

    // doesFileExist :: String -> Bool
    function doesFileExist(strPath) {
        var error = $();
        return $.NSFileManager.defaultManager
            .attributesOfItemAtPathError($(strPath)
                .stringByStandardizingPath, error), error.code === undefined;
    };

    // lines :: String -> [String]
    function lines(s) {
        return s.split(/[\r\n]/);
    };

    // readFile :: FilePath -> maybe String
    function readFile(strPath) {
        var error = $(),
            str = ObjC.unwrap(
                $.NSString.stringWithContentsOfFileEncodingError($(strPath)
                    .stringByStandardizingPath, $.NSUTF8StringEncoding, error)
            ),
            blnValid = typeof error.code !== 'string';
        return {
            nothing: !blnValid,
            just: blnValid ? str : undefined,
            error: blnValid ? '' : error.code
        };
    };

    // show :: a -> String
    function show(x) {
        return JSON.stringify(x, null, 2);
    };

    // TEST -------------------------------------------------------------------
    var strPath = '~/DeskTop/tree.txt';

    return doesFileExist(strPath) ? function () {
        var dctMaybe = readFile(strPath);
        return dctMaybe.nothing ? dctMaybe.error : show(lines(dctMaybe.just));
    }() : 'File not found:\n\t' + strPath;
})();
houthakker
  • 688
  • 5
  • 13