You will usually interact with files through two standard library APIs — |
|
std := load('../vendor/std') writeFile := std.writeFile readFile := std.readFile slice := std.slice log := std.log |
|
Let's read in the README for this project. |
readFile('../README.md', data => ( log('Read:') log( ` data is the entire file content ` slice(data, 0, 16)) )) |
If the read fails, null is passed to the callback. The read can fail if you try to access a file that doesn't exist. So we should handle that. |
readFile('../doesnt-exist.md', data => data :: { () -> log('The read failed.') _ -> log('The read succeeded.') }) |
Here we write content to a file. If the file exists, it's truncated — otherwise the file is created. The path is relative to the executing file. |
path := '../tmp/_writeExample.txt' data := 'Some data. ' writeFile(path, data, cb => cb :: { ` either true or null ` true -> log('The write succeeded.') _ -> log('The write failed.') }) |
|
make('../tmp/_makeExample/', cb => cb.type :: { 'error' -> ( log('Make:') log(' ' + string(cb.message)) ) _ -> log('Make succeeded.') }) |
We can get directory information with |
dir('../src/', cb => cb.type :: { 'error' -> log('Dir failed.') ` cb.data is a list of files and directories` _ -> ( log('Dir:') log(' ' + string(cb.data.0)) ) }) |
Similarly, |
stat('../README.md', cb => cb.type :: { 'error' -> log('Stat failed.') _ -> ( log('Stat:') log(' ' + string(cb)) ) }) |
We're not using ordered callbacks so the order of the logs will be dependant on the system calls when this website was last built and the code was evaluated. This is an example of Ink's event loop! |
$ ink files.ink Read: [![CI](https://g The read failed. Dir: {name: 'build.ink', len: 5710, dir: false, mod: 1626466486} Make succeeded. Stat: {type: 'data', data: {name: 'README.md', len: 2437, dir: false, mod: 1626466486}} The write succeeded. |
Next example: HTTP.