JXA でテキストファイルを読み書きする四つの方法

使用OS: macOS 10.12 

Application.currentApplication()
====================

```js:write-read-example1.js
app = Application.currentApplication()
app.includeStandardAdditions = true

path = app.pathTo("desktop",{from:"user domain"})+"/read_write.txt"

// write
contents = new Date() + " 本日は晴天なり"
try {
	f = app.openForAccess(path, {writePermission:true})
	app.setEof(f, {to:0})
	app.write(contents, {to:f, as:"text"})
} catch(e){
	console.log(e)
	app.displayAlert(e.toString())
} finally {
	app.closeAccess(f)
}

// read
try {
	f = app.openForAccess(path)
	c = app.read(f, {as:"text"})
} catch(e){
	console.log(e)
	app.displayAlert(e.toString())
} finally {
	app.closeAccess(f)
}
c
// "Fri Jun 30 2017 20:18:05 GMT+0900 (JST) 本日は晴天なり"
```

`app.write()` `app.read()` は文字コードを指定する事が出来ない。日本語環境で実行した場合は MacEncoding(Shift_JIS) で処理される。

$.NSString
====================

```js:write-read-example2.js
app = Application.currentApplication()
app.includeStandardAdditions = true

path = app.pathTo("desktop",{from:"user domain"})+"/read_write.txt"

// write
contents = new Date() + " 本日は晴天なり"
p = $(path).stringByStandardizingPath
a = $(true)
u = $.NSUTF8StringEncoding
e = $()
$(contents).writeToFileAtomicallyEncodingError(p, a, u, e)
if (e.js) {
	m = $.NSString.stringWithFormat("%@", e).js
	console.log(m)
	app.displayAlert(m)
}

// read
p = $(path).stringByStandardizingPath
u = $.NSUTF8StringEncoding
e = $()
c = $.NSString.stringWithContentsOfFileEncodingError(p, u, e).js
if (e.js) {
	m = $.NSString.stringWithFormat("%@", e).js
	console.log(m)
	app.displayAlert(m)
}
c
// "Fri Jun 30 2017 20:18:05 GMT+0900 (JST) 本日は晴天なり"
```

`$.NSUTF8StringEncoding` を使用しているので文字コードは`UTF-8`となる。

$.NSFileManager
====================

```js:write-read-example3.js
app = Application.currentApplication()
app.includeStandardAdditions = true

path = app.pathTo("desktop",{from:"user domain"})+"/read_write.txt"

// write
contents = new Date() + " 本日は晴天なり"
p = $(path).stringByStandardizingPath
u = $.NSUTF8StringEncoding
c = $(contents).dataUsingEncoding(u)
a = $()
r = $.NSFileManager.defaultManager.createFileAtPathContentsAttributes(p, c, a)
if (!r) {
	m = "Error: file write faild."
	console.log(m)
	app.displayAlert(m)
}

// read
p = $(path).stringByStandardizingPath
d = $.NSFileManager.defaultManager.contentsAtPath(p)
u = $.NSUTF8StringEncoding
c = $.NSString.alloc.initWithDataEncoding(d, u)
// "Fri Jun 30 2017 20:18:05 GMT+0900 (JST) 本日は晴天なり"
```

読み込み失敗時のエラーは発生せず空文字が返ってくるので自前で存在確認等が必要。

$.NSFileHandle
====================

```js:write-read-example4.js
app = Application.currentApplication()
app.includeStandardAdditions = true
fm = $.NSFileManager.defaultManager

path = app.pathTo("desktop",{from:"user domain"})+"/read_write.txt"

// write
contents = new Date() + " 本日は晴天なり"
try {
	f = $()
	p = $(path).stringByStandardizingPath
	if (!fm.fileExistsAtPath(p)) {
		c = $.NSData.data
		a = $()
		if (!fm.createFileAtPathContentsAttributes(p, c, a)) {
			throw new Error("Create file failed, " + path)
		}
	}
	u = $.NSUTF8StringEncoding
	d = $(contents).dataUsingEncoding(u)
	f = $.NSFileHandle.fileHandleForWritingAtPath(p)
	f.seekToFileOffset(0)
	f.writeData(d)
	f.truncateFileAtOffset(d.length)
} catch(e) {
	console.log(e)
	app.displayAlert(e.toString())
} finally {
	if (f.js) {
		f.synchronizeFile
		f.closeFile
	}
}

// read
try {
	p = $(path).stringByStandardizingPath
	f = $.NSFileHandle.fileHandleForReadingAtPath(p)
	if (!f.js) throw new Error("Open file failed, " + path)
	d = f.readDataToEndOfFile
	u = $.NSUTF8StringEncoding
	c = $.NSString.alloc.initWithDataEncoding(d, u).js
} catch(e) {
	console.log(e)
	app.displayAlert(e.toString())
} finally {
	if (f.js) f.closeFile
}
c
// "Fri Jun 30 2017 20:18:05 GMT+0900 (JST) 本日は晴天なり"
```

$.NSString の方法を関数化
====================
```js:write-read-example4.js
function readFrom(path, encoding) {
	var p = $(path).stringByStandardizingPath
	var u = encoding || $.NSUTF8StringEncoding
	var e = $()
	var c = $.NSString.stringWithContentsOfFileEncodingError(p, u, e).js
	if (e.js) {
		throw new Error($.NSString.stringWithFormat("%@", e).js)
	}
	return c
}
function writeTo(contents, path, encoding) {
	var p = $(path).stringByStandardizingPath
	var a = $(true)
	var u = encoding || $.NSUTF8StringEncoding
	var e = $()
	$(contents).writeToFileAtomicallyEncodingError(p, a, u, e)
	if (e.js) {
		throw new Error($.NSString.stringWithFormat("%@", e).js)
	}
}
function append(contents, path, encoding) {
	if ($.NSFileManager.defaultManager.fileExistsAtPath($(path).stringByStandardizingPath)) {
		var c = readFrom(path, encoding)
	} else {
		var c = ""
	}
	writeTo(c + contents, path, encoding)
}
if (!String.readFrom) {
	String.readFrom = readFrom
}
if (!String.prototype.writeTo) {
	String.prototype.writeTo = function(path, encoding) {
		writeTo(this.toString(), path, encoding)
	}
}
if (!String.prototype.appendTo) {
	String.prototype.appendTo = function(path, encoding) {
		append(this.toString(), path, encoding)
	}
}

p = $.NSHomeDirectory().js + "/Desktop/read_write.txt"

new Date().toString().writeTo(p)

" 本日は晴天なり".appendTo(p)

String.readFrom(p)
// "Fri Jun 30 2017 20:18:05 GMT+0900 (JST) 本日は晴天なり"
```