A library for iterating through the lines in a series of files. Very similar to the Python module of the same name.
It allows the programmer to automatically take filenames from the command line arguments (via input
and input_state
), as well as specify them as a vector directly (input_vec
and input_vec_state
). The files are opened as necessary, so any files that can't be opened only cause an error when reached in the iteration.
On the command line, stdin
is represented by a filename of -
(a single hyphen) and in the functions that take a vector directly (e.g. input_vec
) it is represented by None
. Note stdin
is not reset once it has been finished, so attempting to iterate on [None, None]
will only take input once unless io::stdin().seek(0, SeekSet)
is called between.
The pathify
function handles converting a list of file paths as strings to the appropriate format, including the (optional) conversion of "-"
to stdin
.
In many cases, one can use the input_*
functions without having to handle any FileInput
structs. E.g. a simple cat
program
for input |line| {
io::println(line)
}
or a program that numbers lines after concatenating two files
for input_vec_state(pathify([~"a.txt", ~"b.txt"])) |line, state| {
io::println(fmt!("%u: %s", state.line_num,
line));
}
The two input_vec*
functions take a vec of file names (where empty means read from stdin
), the other two functions use the command line arguments.
For more complicated uses (e.g. if one needs to pause iteration and resume it later), a FileInput
instance can be constructed via the from_vec
, from_vec_raw
and from_args
functions.
Once created, the each_line
(from the std::io::ReaderUtil
trait) and each_line_state
methods allow one to iterate on the lines; the latter provides more information about the position within the iteration to the caller.
It is possible (and safe) to skip lines and files using the read_line
and next_file
methods. Also, FileInput
implements std::io::Reader
, and the state will be updated correctly while using any of those methods.
E.g. the following program reads until an empty line, pauses for user input, skips the current file and then numbers the remaining lines (where the numbers are from the start of each file, rather than the total line count).
let in = FileInput::from_vec(pathify([~"a.txt", ~"b.txt", ~"c.txt"],
true));
for in.each_line |line| {
if line.is_empty() {
break
}
io::println(line);
}
io::println("Continue?");
if io::stdin().read_line() == ~"yes" {
in.next_file(); // skip!
for in.each_line_state |line, state| {
io::println(fmt!("%u: %s", state.line_num_file,
line))
}
}
FileInput
FileInputState
- A summary of the internal state of a FileInput
objectfor FileInput
of io::Reader for FileInput
input
- Iterate directly over the command line arguments (no arguments implies reading from stdin
).input_state
input_vec
- Iterate over a vector of files (an empty vector implies just stdin
).input_vec_state
pathify
- Convert a list of strings to an appropriate form for a FileInput
instanceFileInput
pub struct FileInput {
priv fi: @mut FileInput_,
}
FileInputState
pub struct FileInputState {
current_path: Option<Path>,
line_num: uint,
line_num_file: uint,
}
A summary of the internal state of a FileInput
object. line_num
and line_num_file
represent the number of lines read in total and in the current file respectively. current_path
is None
if the current file is stdin
.
FileInput
from_vec
fn from_vec(files: ~[Option<Path>]) -> FileInput
Create a FileInput
object from a vec of files. An empty vec means lines are read from stdin
(use from_vec_raw
to stop this behaviour). Any occurence of None
represents stdin
.
from_vec_raw
fn from_vec_raw(files: ~[Option<Path>]) -> FileInput
Identical to from_vec
, but an empty files
vec stays empty. (None
is stdin
.)
from_args
fn from_args() -> FileInput
Create a FileInput
object from the command line arguments. "-"
represents stdin
.
next_file
fn next_file(&self) -> bool
Skip to the next file in the queue. Can fail
when opening a file.
Returns false
if there is no more files, and true
when it successfully opens the next file.
each_line_state
fn each_line_state(&self, f: &fn(&str, FileInputState) -> bool) -> bool
Apply f
to each line successively, along with some state (line numbers and file names, see documentation for FileInputState
). Otherwise identical to lines_each
.
state
fn state(&self) -> FileInputState
Retrieve the current FileInputState
information.
io::Reader
for FileInput
read_byte
fn read_byte(&self) -> int
read
fn read(&self, buf: &mut [u8], len: uint) -> uint
eof
fn eof(&self) -> bool
seek
fn seek(&self, offset: int, whence: io::SeekStyle)
tell
fn tell(&self) -> uint
input
fn input(f: &fn(&str) -> bool) -> bool
Iterate directly over the command line arguments (no arguments implies reading from stdin
).
Fails when attempting to read from a file that can't be opened.
input_state
fn input_state(f: &fn(&str, FileInputState) -> bool) -> bool
Iterate directly over the command line arguments (no arguments implies reading from stdin
) with the current state of the iteration provided at each call.
Fails when attempting to read from a file that can't be opened.
input_vec
fn input_vec(files: ~[Option<Path>], f: &fn(&str) -> bool) -> bool
Iterate over a vector of files (an empty vector implies just stdin
).
Fails when attempting to read from a file that can't be opened.
input_vec_state
fn input_vec_state(files: ~[Option<Path>],
f: &fn(&str, FileInputState) -> bool) -> bool
Iterate over a vector of files (an empty vector implies just stdin
) with the current state of the iteration provided at each call.
Fails when attempting to read from a file that can't be opened.
pathify
fn pathify(vec: &[~str], stdin_hyphen: bool) -> ~[Option<Path>]
Convert a list of strings to an appropriate form for a FileInput
instance. stdin_hyphen
controls whether -
represents stdin
or a literal -
.