This Python script provides a small command-line utility that can split a stream of bytes (from standard input) into many chunk files, and concatenate those chunk files back to a single stream (written to standard output). It’s designed to be flexible by letting you define how files are created, saved, and read using your own shell commands.
- split: reads data from
stdinin fixed-size pieces and writes each piece to a new file. It can group files into numbered directories. - concat: reads those files back in order and writes their contents to
stdout.
Both operations delegate the actual filesystem work (mkdir, write, read) to external commands you specify. This makes the tool adaptable to many environments (local disk, special devices, custom commands, etc.).
-
Templates for names You supply Python format templates for directory and file names, e.g.
d{:05d}orf{:05d}. The script fills in the sequence numbers (0, 1, 2, …). -
External command templates You pass shell command templates for:
- making directories (
--mkdir), - saving data from
stdin(--save), - reading data to
stdout(--cat).
Placeholders:
{dn}→ the directory name{fn}→ the file name
- making directories (
-
Chunking and grouping You can choose the maximum bytes per file (default: 1 MiB) and the maximum files per directory (default: 1000). When the file count hits the limit, the tool moves to the next directory.
-
The
MyClassobject stores templates and wraps three helpers:_do_mkdir(dir_name)runs the mkdir command (if provided)._do_save(dir_name, file_name, data)runs the save command and writes the chunk to the process’sstdin._do_cat(dir_name, file_name, stdout)runs the read command and pipes its output to the tool’sstdout.
-
Split loop Repeatedly read up to
max_bytesfromstdin. For each non-empty read:- Format the next file name.
- Call the save command.
- Increment counters; roll over to a new directory when needed.
-
Concat loop Iterate file indices in order. For each file:
- Format the file name.
- Run the cat command and stream it to
stdout. - If the command returns non-zero (treated as “no more files”), stop.
- Roll over to the next directory after
files_per_dirfiles.
The tool has two subcommands: split and concat.
python3 tool.py split \
--dir "d{:05d}" \
--file "f{:05d}" \
--mkdir "mkdir -p {dn}" \
--save "dd of={dn}/{fn}" \
--max-bytes 1048576 \
--files-per-dir 1000- Reads from
stdin, writes chunk files liked00000/f00000,d00000/f00001, … - You can swap
ddfortee {dn}/{fn} >/dev/nullor any writer that reads fromstdin.
Example usage:
cat bigfile.bin | python3 tool.py split --mkdir "mkdir -p {dn}" --save "dd of={dn}/{fn}"python3 tool.py concat \
--dir "d{:05d}" \
--file "f{:05d}" \
--cat "dd if={dn}/{fn}" \
--files-per-dir 1000 > rejoined.bin- Reads files back in order, starting at
d00000/f00000, and writes tostdout.
Example usage:
python3 tool.py concat --cat "cat {dn}/{fn}" > restored.bin- Different storage backends: Point
--saveand--catto commands that interact with special paths, devices, or network tools. - Name schemes: Use any Python format spec like
chunks_{0:04d}orpart_{0:06d}.binto match your conventions. - Directory strategy: Adjust
--files-per-dirto avoid huge directories on filesystems that slow down with many entries.
- Return codes matter: The tool treats any non-zero exit code during concat as “no more files.” Ensure your
--catcommand behaves accordingly. - Defaults review: The default
--mkdirin the script you pasted ismkdir -p {dn}/{fn}which tries to create a directory path including the file name. You’ll likely wantmkdir -p {dn}instead. - Atomicity and retries: There’s no retry logic; failed commands raise errors.
- No integrity checks: Consider adding checksums or verification if data correctness is critical.
- Splitting huge files for storage/transfer limits.
- Streaming pipelines where chunking and reassembly must integrate with existing shell tools.
- Environments that require custom IO commands (e.g.,
dd, device files, or specialized CLI clients).
In short, this script offers a small, adaptable “glue” layer: you decide the file layout and the exact commands, and it handles the counting, chunking, and ordering.