>>  <<  Usr  Pri  JfC  LJ  Phr  Dic  Rel  Voc  !:  Help  User

Component Files (jfiles)

Jfiles are component files for J data. A jfile can be thought of as a boxed list which is stored on file. An element of the boxed list is referred to as a component, and can store a noun of any type, shape or size. File components are numbered sequentially from 0 upwards.

To access the system (assuming you are using the standard profile):

   load 'jfiles'

This populates a locale jfiles with utility functions, and defines the following verbs in the z locale:


You create a file using jcreate.

jappend adds new items to the file. Each item added to the file is stored in a new component. Several items can be added to the file at a time.

jread reads items from file, and jreplace replaces items on file.

jdup duplicates a file, and jsize returns its size.

You can refer to a file either by its file name, or by its file handle. The default file extension is .ijf - this is used if no file extension is given.

You cannot delete components once created. If you need to reclaim space no longer required, either replace the components with empties, or else duplicate the file, copying only the components required.

Create file
create a file. The right argument is the filename. Any existing file is overwritten. The result is 1 if successful, else 0. For example:

   jcreate 'mydata'

Note that since the file extension was not specified, this actually creates a file named mydata.ijf.

Read and write file
append to file. The left argument is a boxed list, with each item in the list stored in a new file component. An open noun is treated as a single boxed item. The right argument is the filename. The result is the new component numbers created. For example:

   'header' jappend 'mydata'

   ('rec1';'rec2') jappend 'mydata'
1 2

   (< <\1 2 3) jappend 'mydata'

   (2 2$10 20 30 40) jappend 'mydata'

read file. The right argument is the filename, linked with one or more component numbers. The result has the same shape as the component numbers. For example:

   > jread 'mydata';4
10 20
30 40
   jread 'mydata';i.5
|header|rec1|rec2|+-+---+-----+|10 20|
|      |    |    ||1|1 2|1 2 3||30 40|
|      |    |    |+-+---+-----+|     |

   jread 'mydata';i.2 2
|header|rec1         |
|rec2  |+-+---+-----+|
|      ||1|1 2|1 2 3||
|      |+-+---+-----+|

replace in file. The result is the components replaced. For example:

   (1000;'abcde') jreplace 'mydata';1 2
1 2

   jread 'mydata';i.3

The left argument is reshaped if necessary to match the components in the right argument. For example, the following replaces components 1-3, each with the word 'reserved':

   'reserved' jreplace 'mydata';1 2 3
1 2 3

duplicate file. The left argument is the new filename; if elided, the file is duplicated in place. The right argument is the source filename, optionally linked with one or more component numbers to be copied to the new file, in the order given. By default, the entire file is duplicated. The result is the number of components written. For example:

   'newdata' jdup 'mydata'
   'newdata' jdup 'mydata';2 0 1

size of file, as 4 numbers:

starting component number (0)
number of components
length of file in bytes (same as result of 1!:4)
amount of free space that could be recovered by duplicating the file

For example:

   jsize 'newdata'
0 5 1312 0

erase file, for example:

   jerase 'newdata'

File handles
You can refer to a file either by its filename, or by its file handle if you have already opened the file. For most purposes we recommend using the filename. However, if you have a great deal of file activity, you may find it faster to open the file first, then use the file handle; this means the system does not have to open and close the file each time it is accessed. The utilities jopen and jclose in the jfiles locale can be used for this purpose. For example:

   h=. jopen_files_ 'mydata'

... process file using handle h...

   jclose_files_ h

File structure
Each file is structured as a header record, followed by data. The header record is as follows:

[0] version
[1] starting component
[2] number of components
[3] file length
[4] directory pointer
[5] freelist pointer
[6] sequence number

Each component is stored in its 3!:1 representation in a space that is a power of 2. This means that on average, the representation fills 75% of the space allocated, and allows some space for growing replaces. If the space required on replacement is less than half the space allocated, then the balance is freed up.

If you replace a component with a noun of smaller size, then this may result in some unused space. The system keeps track of this in the freelist, and attempts to reuse it where possible. The total free space available is given in the fourth element of the result of jsize, and this is the space that would be freed by duplicating the file using jdup.

>>  <<  Usr  Pri  JfC  LJ  Phr  Dic  Rel  Voc  !:  Help  User