Rust input/output: Difference between revisions
From wikinotes
(→Stdin) |
|||
(One intermediate revision by the same user not shown) | |||
Line 9: | Line 9: | ||
= Stdin, Stdout, Stderr = | = Stdin, Stdout, Stderr = | ||
<blockquote> | |||
== Stdout/Stderr == | |||
<blockquote> | <blockquote> | ||
<syntaxhighlight lang="rust"> | <syntaxhighlight lang="rust"> | ||
Line 14: | Line 16: | ||
eprintln!("err"); // write to stderr | eprintln!("err"); // write to stderr | ||
</syntaxhighlight> | </syntaxhighlight> | ||
</blockquote><!-- Stdout/Stderr --> | |||
read from stdin | == Stdin == | ||
<blockquote> | |||
{{ NOTE | | |||
rust nightly has a [https://doc.rust-lang.org/std/io/trait.IsTerminal.html std::io::IsTerminal] that checks if the stream is a pipe or a tty.<br> | |||
but besides this there is no builtin way to verify this.<br> | |||
you can do it manually with [[rust libc]], but the most portable way is to use [[rust atty]]. | |||
}} | |||
read from stdin | |||
<syntaxhighlight lang="rust"> | <syntaxhighlight lang="rust"> | ||
extern crate atty; | |||
use std::io; | use std::io; | ||
use std::io::BufRead; | use std::io::BufRead; | ||
Line 22: | Line 34: | ||
/// read big files | /// read big files | ||
fn buffered_read_all_stdin() { | fn buffered_read_all_stdin() { | ||
// don't read unless stdin is a pipe | |||
if atty::is(atty::Stream::Stdin) { | |||
return | |||
} | |||
let stdin = io::stdin(); | let stdin = io::stdin(); | ||
let handle = stdin.lock(); | let handle = stdin.lock(); | ||
Line 32: | Line 48: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
manual buffered read | |||
<syntaxhighlight lang="rust"> | <syntaxhighlight lang="rust"> | ||
extern crate atty; | |||
use std::io::Read; | use std::io::Read; | ||
use std::str; | use std::str; | ||
Line 39: | Line 56: | ||
/// like `tail -f` | /// like `tail -f` | ||
fn manually_buffered_read_stdin() { | fn manually_buffered_read_stdin() { | ||
let mut buffer: [u8; | // don't read unless stdin is a pipe | ||
if atty::is(atty::Stream::Stdin) { | |||
return | |||
} | |||
let mut buffer: [u8; 1024] = [0; 1024]; | |||
let stdin = io::stdin(); | let stdin = io::stdin(); | ||
let mut handle = stdin.lock(); | let mut handle = stdin.lock(); | ||
Line 56: | Line 78: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
</blockquote><!-- Stdin --> | |||
</blockquote><!-- Stdin, Stdout, Stderr --> | </blockquote><!-- Stdin, Stdout, Stderr --> | ||
Latest revision as of 08:34, 9 February 2023
Documentation
std::fs
https://doc.rust-lang.org/std/fs/index.html
Stdin, Stdout, Stderr
Stdout/Stderr
println!("out"); // write to stdout eprintln!("err"); // write to stderrStdin
NOTE:
rust nightly has a std::io::IsTerminal that checks if the stream is a pipe or a tty.
but besides this there is no builtin way to verify this.
you can do it manually with rust libc, but the most portable way is to use rust atty.read from stdin
extern crate atty; use std::io; use std::io::BufRead; /// read big files fn buffered_read_all_stdin() { // don't read unless stdin is a pipe if atty::is(atty::Stream::Stdin) { return } let stdin = io::stdin(); let handle = stdin.lock(); let lines: Vec<String> = handle .lines() .map(|res| res.unwrap_or_default()) .collect(); print!("START\n{}\nFINISH\n", lines.join("\n")); }manual buffered read
extern crate atty; use std::io::Read; use std::str; /// like `tail -f` fn manually_buffered_read_stdin() { // don't read unless stdin is a pipe if atty::is(atty::Stream::Stdin) { return } let mut buffer: [u8; 1024] = [0; 1024]; let stdin = io::stdin(); let mut handle = stdin.lock(); loop { let bytes_read = handle .read(&mut buffer[..]) .unwrap_or(0); // reached EOF if bytes_read == 0 { break; } print!("{}", str::from_utf8(&buffer).unwrap()); } }
User Input
let name = String::new(); io::stdin().read_line(&mut name);