Skip to content

How to work with files

This page explains how q names files and resolves paths. The formats themselves — text, binary, native KDB-X, and those reached through interfaces — each have their own page.

Every file operation in q starts from a file handle: a symbol that names a file or directory. The same handle serves read and write, and the shape of the data you pass decides which format you get.

File handles

A file handle is a symbol whose name begins with a colon. For example, this is the handle for the file new.txt in the current directory:

`:new.txt

The name after the colon is an optional relative or absolute path followed by the file name. Handles are a special form of symbol, distinguished only by that leading colon. Use hsym to convert an existing symbol into a handle rather than assembling the name by hand:

q)hsym `$"/tmp/test.txt"
`:/tmp/test.txt

hsym is idempotent, so it is safe to apply to a name that may already be a handle — useful when the path is assembled at run time:

q)hsym hsym `$"/tmp/test.txt"
`:/tmp/test.txt

Note that q always displays / as the path separator, even on Windows, where you can type either / or \.

Resolving relative paths

q reads files from relative or absolute paths. When it resolves a relative path, it searches these locations in order:

  1. The current directory
  2. The directory named by the QHOME environment variable
  3. The directory named by the QLIC environment variable

So a file new.txt that exists only under QHOME is found from any working directory:

q)getenv `QHOME                       / location where new.txt is stored
"/Users/myuser/Development/q"
q)\pwd                                / current directory, which has no new.txt
"/tmp"
q)read0 `:new.txt
"I'm stored in QHOME!!"

Because the current directory is searched first, a file with the same name there takes precedence:

q)\pwd
"/tmp"
q)read0 `:new.txt
"I'm stored in the current directory!!!"

Absolute paths for anything long-lived

Search-order resolution is convenient when using q interactively but also means a script result depends on where it runs from. Use hsym on an absolute path in code you intend to keep.

The formats

The same handle serves read and write, and the shape of the data you pass decides which format you get:

  • Text files — delimited and fixed-width records, key-value text, JSON, and streaming an input too large to hold in memory.
  • Binary files — raw bytes and fixed-width binary records, with no type information of their own.
  • KDB-X formatted files — q's own format, which records type and attributes so a file can be mapped straight back into memory.
  • External file formats — Parquet through the built-in module, and the interfaces reaching Python, Arrow, ODBC and HDF5.
  • File utilities — size, directory listing, existence, deletion, and running shell commands.

Next steps