These patches add new file I/O capabilities to J through three feature groups: readline functions, virtual (RAM-based) files, and character-level I/O control.
Note: Most patches are standalone. Only virtual-files requires readline-functions. See Applying the Patches for details.
Patch: readline-functions.patch
These functions provide line-by-line file reading, complementing J’s existing block-based file operations:
| Function | Description | Newline Handling |
|---|---|---|
1!:13 |
Read one line | Includes newline |
1!:14 |
Read one line (trimmed) | Strips CR/LF |
1!:15 |
Peek one line | Strips CR/LF, doesn’t advance position |
NB. Open a file for reading
f =. 1!:21 <'data.txt'
NB. Read line by line (includes newline)
line1 =. 1!:13 f
line2 =. 1!:13 f
NB. Read line without trailing newline
clean_line =. 1!:14 f
NB. Peek at next line without consuming it
next =. 1!:15 f
same =. 1!:15 f NB. Returns same content
NB. Close file
1!:22 fprocess_file =: 3 : 0
f =. 1!:21 <y
result =. ''
while. 0 < # line =. 1!:14 f do.
result =. result , process_line line
end.
1!:22 f
result
)The implementation uses C’s fgets() to read lines up to
1000 characters. For regular files:
1!:13 (jtjfreadline): Wraps
fgets(), returns result as-is1!:14 (jtjfreadlinetrim): Strips
trailing \r and \n characters1!:15 (jtjfreadlinepeek): Uses
ftell()/fseek() to restore position after
readingSpecial file handles are supported:
1: Keyboard input (uses J’s internal
jgets)3: Standard inputPatch: virtual-files.patch
Virtual files exist entirely in RAM and behave like regular files. They’re useful for: - Temporary data without filesystem overhead - Testing file-handling code - In-memory buffers with file semantics - Inter-component communication within J
NB. Create with automatic name
vf =. 1!:60 ''
NB. Create with custom name (for debugging)
vf =. 1!:60 'mybuffer'
NB. The returned handle (>= 1000000) works with all file operationsNB. Create a virtual file
vf =. 1!:60 'test'
NB. Write data
'Hello, World!' 1!:2 vf
NB. Read it back
data =. 1!:1 vf NB. Returns: Hello, World!
NB. Append more data
' More text.' 1!:3 vf
NB. Check size
size =. 1!:4 vf NB. Returns: 24
NB. Read line by line
1!:14 vf NB. Works with readline functions too!Virtual files use a custom VirtFile structure:
typedef struct {
C *data; // Content buffer (auto-grows)
I size; // Current content size
I capacity; // Allocated buffer size
I position; // Read/write position
I magic; // 0x56465249 ('VFIR') identifies virtual files
I virtid; // Unique ID >= 1000000
pthread_rwlock_t lock; // Thread safety
} VirtFile;Key features:
1!:1,
1!:2, 1!:3, 1!:4,
1!:13, 1!:14, 1!:15Patch: char-io-control.patch
Provides character-level terminal control for building interactive applications:
| Mode | Description |
|---|---|
(1!:111) 1 |
Read character with echo |
(1!:111) 0 |
Enter silent mode / read without echo |
(1!:111) _1 |
Restore normal terminal |
(1!:111) 2 |
Flush stdout immediately |
Note: Parentheses are required due to J’s parsing of 3-digit numbers.
NB. Read single character with echo (like normal typing)
char =. (1!:111) 1
NB. Enter silent mode (for password input, etc.)
(1!:111) 0 NB. First call enters silent mode
c1 =. (1!:111) 0 NB. Subsequent calls read silently
c2 =. (1!:111) 0
(1!:111) _1 NB. Restore normal echo
NB. Immediate output (essential for character-by-character display)
'Press any key: ' 1!:2 (4) NB. Write to stdout
(1!:111) 2 NB. Flush - text appears immediately
key =. (1!:111) 1 NB. Wait for keypressmenu =: 3 : 0
echo 'Choose an option:'
echo ' [a] Add item'
echo ' [d] Delete item'
echo ' [q] Quit'
'Choice: ' 1!:2 (4)
(1!:111) 2 NB. Flush prompt
choice =. (1!:111) 1 NB. Get single keypress with echo
echo '' NB. Newline after choice
choice
)The function uses platform-specific APIs:
Unix/Linux (termios):
// Disable canonical mode and echo
new_tio.c_lflag &= ~ICANON; // Character-at-a-time input
new_tio.c_lflag &= ~ECHO; // Silent mode
tcsetattr(STDIN_FILENO, TCSANOW, &new_tio);
// Read single character
read(STDIN_FILENO, &c, 1);Windows (conio.h):
c = _getch(); // Silent read
c = _getche(); // Read with echoGlobal state management ensures: - Terminal settings are saved before
modification - Silent mode persists across multiple reads - Original
settings are restored on (1!:111) _1
readline-functions.patch (standalone)
virtual-files.patch (requires readline-functions)
char-io-control.patch (standalone)
Note: Only virtual-files has a functional dependency on readline (it extends readline to work with RAM-based files). The other patches are independent.
cd /path/to/jsource
git apply readline-functions.patchStandalone patch - can be applied independently.
cd /path/to/jsource
git apply readline-functions.patch
git apply virtual-files.patchVirtual files extends the readline functions to work with RAM-based files.
cd /path/to/jsource
git apply char-io-control.patchStandalone patch - can be applied independently.
When applying all patches together, apply in this order:
cd /path/to/jsource
git apply downloads/file-io-enhancements/readline/readline-functions.patch
git apply downloads/file-io-enhancements/virtual-files/virtual-files.patch
git apply downloads/file-io-enhancements/char-io/char-io-control.patchOr apply just the ones you need - readline and char-io work independently
| Function | Purpose | Patch |
|---|---|---|
1!:13 |
Read line (with newline) | readline-functions |
1!:14 |
Read line (trimmed) | readline-functions |
1!:15 |
Peek line | readline-functions |
1!:60 |
Create virtual file | virtual-files |
(1!:111) 0/1/_1/2 |
Character I/O control | char-io-control |