Golang test stdout [duplicate] - testing

This question already has answers here:
How to test a function's output (stdout/stderr) in unit tests
(3 answers)
Closed 3 years ago.
I am trying to test some functions that print ANSI escape codes. e.g.
// Print a line in a color
func PrintlnColor(color string, a ...interface{}) {
fmt.Print("\x1b[31m")
fmt.Print(a...)
fmt.Println("\x1b[0m")
}
I tried using Examples to do it, but they don't seem to like escape codes.
Is there any way to test what is written to stdout?

Using fmt.Fprint to print to io.Writer lets you control where the output is written.
var out io.Writer = os.Stdout
func main() {
// write to Stdout
PrintlnColor("foo")
buf := &bytes.Buffer{}
out = buf
// write to buffer
PrintlnColor("foo")
fmt.Println(buf.String())
}
// Print a line in a color
func PrintlnColor(a ...interface{}) {
fmt.Fprint(out, "\x1b[31m")
fmt.Fprint(out, a...)
fmt.Fprintln(out, "\x1b[0m")
}
Go play

Related

What is the cleanest way to return the error when matching a Result<T, E>? [duplicate]

This question already has answers here:
Is there any way of doing unwrap_or_return an Error (any error)
(1 answer)
What is this question mark operator about?
(4 answers)
Closed 2 years ago.
I'm calling a function that returns a Result<T, E> and I want to handle the Ok case but return the Err as is if an error is returned. What is the cleanest way to do this?
For example, I have:
fn example() -> Result<(), Error> {
match foo() {
Ok(v) => bar(v),
Err(e) => Err(e),
}
}
What are some alternate forms of writing this? It feels weird to re-wrap e in another Err in every call in the stack. Also, every call is basically 4 lines of boilerplate... I'm just looking for a way to simplify and make it more readable. My desire is to have it return the error if error, else process the result value.
Rust includes an 'error propagation' operator, ?. If the value of the Result it is called on is Ok it will unwrap and return the inner value. If the value is Err it will return from the function and pass the Err to the caller.
fn example() -> Result<(), Error> {
let v = foo()?;
bar(v);
}

print!() executes after the input is entered [duplicate]

This question already has answers here:
Why does this read input before printing?
(3 answers)
Closed 3 years ago.
i want to know why the print!() macro here executes after the read_line
// ./src/main.rs
use std::io;
fn main() {
print!("Input : ");
let stdin = io::stdin();
let mut input = String::new();
stdin.read_line(&mut input).expect("Couldn't read_line");
}
This code prints out :
heyy
Input :
But i expect :
Input : heyy
You can read the Rust documentation here: https://doc.rust-lang.org/std/macro.print.html
Specifically, this line:
"Note that stdout is frequently line-buffered by default so it may be necessary to use io::stdout().flush() to ensure the output is emitted immediately.
This is pretty common when working with the terminal in most languages. stdout is buffered on almost all terminals. You can turn it off on some AFAIK but you're better of just either calling flush as they suggest or I believe most terminals will flush their output if you write a new line to it.
This is how I solved the problem(thanks to Vaughan Hills) :
// Returns the input for a given message - msg
fn input(msg : &str) -> String {
let mut input = String::new();
print!("{}", msg);
io::stdout().flush().unwrap();
io::stdin().read_line(&mut input).unwrap();
input.trim().to_string()
}

From Option to iterator [duplicate]

This question already has answers here:
How to convert an Option<T> to an iterator of zero or one element?
(1 answer)
How can I iterate on an Option<Vec<_>>?
(4 answers)
Closed 4 years ago.
I have a function which consumes an iterator:
fn func<T: iter::Iterator<Item = char>>(i: T) {
//...
}
I need to write a function whose input is an Option<char> (type char is not important here, just for illustrative purpose), and depends on the value of input, it should create an empty or an once iterator. My solution is:
use std::iter;
fn option_iter(input: Option<char>) {
let i: Box<iter::Iterator<Item = char>> = if let Some(input) = input {
Box::new(iter::once(input))
} else {
Box::new(iter::empty())
};
}
I find this ugly because of type erasure by Box. I cannot use:
let i = if let Some(input) = input {
iter::once(input)
} else {
iter::empty()
};
func(i);
because the compiler complains the types of two branches are different. Is there any method which does not use Box for this situation?
Option has an iter method that does what you want.

How to test a function's output (stdout/stderr) in unit tests

I have a simple function I want to test:
func (t *Thing) print(min_verbosity int, message string) {
if t.verbosity >= minv {
fmt.Print(message)
}
}
But how can I test what the function actually sends to standard output? Test::Output does what I want in Perl. I know I could write all my own boilerplate to do the same in Go (as described here):
orig = os.Stdout
r,w,_ = os.Pipe()
thing.print("Some message")
var buf bytes.Buffer
io.Copy(&buf, r)
w.Close()
os.Stdout = orig
if(buf.String() != "Some message") {
t.Error("Failure!")
}
But that's a lot of extra work for every single test. I'm hoping there's a more standard way, or perhaps an abstraction library to handle this.
One thing to also remember, there's nothing stopping you from writing functions to avoid the boilerplate.
For example I have a command line app that uses log and I wrote this function:
func captureOutput(f func()) string {
var buf bytes.Buffer
log.SetOutput(&buf)
f()
log.SetOutput(os.Stderr)
return buf.String()
}
Then used it like this:
output := captureOutput(func() {
client.RemoveCertificate("www.example.com")
})
assert.Equal(t, "removed certificate www.example.com\n", output)
Using this assert library: http://godoc.org/github.com/stretchr/testify/assert.
You can do one of three things. The first is to use Examples.
The package also runs and verifies example code. Example functions may include a concluding line comment that begins with "Output:" and is compared with the standard output of the function when the tests are run. (The comparison ignores leading and trailing space.) These are examples of an example:
func ExampleHello() {
fmt.Println("hello")
// Output: hello
}
The second (and more appropriate, IMO) is to use fake functions for your IO. In your code you do:
var myPrint = fmt.Print
func (t *Thing) print(min_verbosity int, message string) {
if t.verbosity >= minv {
myPrint(message) // N.B.
}
}
And in your tests:
func init() {
myPrint = fakePrint // fakePrint records everything it's supposed to print.
}
func Test...
The third is to use fmt.Fprintf with an io.Writer that is os.Stdout in production code, but bytes.Buffer in tests.
You could consider adding a return statement to your function to return the string that is actually printed out.
func (t *Thing) print(min_verbosity int, message string) string {
if t.verbosity >= minv {
fmt.Print(message)
return message
}
return ""
}
Now, your test could just check the returned string against an expected string (rather than the print out). Maybe a bit more in-line with Test Driven Development (TDD).
And, in your production code, nothing would need to change, since you don't have to assign the return value of a function if you don't need it.

File I/O in Every Programming Language [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
This has to be a common question that all programmers have from time to time.
How do I read a line from a text file? Then the next question is always how do i write it back.
Of course most of you use a high level framework in day to day programming (which are fine to use in answers) but sometimes it's nice to know how to do it at a low level too.
I myself know how to do it in C, C++ and Objective-C, but it sure would be handy to see how it's done in all of the popular languages, if only to help us make a better decision about what language to do our file io in. In particular I think it would be interesting to see how its done in the string manipulation languages, like: python, ruby and of course perl.
So I figure here we can create a community resource that we can all star to our profiles and refer to when we need to do file I/O in some new language. Not to mention the exposure we will all get to languages that we don't deal with on a day to day basis.
This is how you need to answer:
Create a new text file called "fileio.txt"
Write the first line "hello" to the text file.
Append the second line "world" to the text file.
Read the second line "world" into an input string.
Print the input string to the console.
Clarification:
You should show how to do this in one programming language per answer only.
Assume that the text file doesn't exist beforehand
You don't need to reopen the text file after writing the first line
No particular limit on the language.
C, C++, C#, Java, Objective-C are all great.
If you know how to do it in Prolog, Haskell, Fortran, Lisp, or Basic then please go right ahead.
LOLCODE
The specs are sketchy to say the least, but I did the best I could. Let the downvoting begin! :) I still find it a fun exercise.
HAI
CAN HAS STDIO?
PLZ OPEN FILE "FILEIO.TXT" ITZ "TehFilez"?
AWSUM THX
BTW #There is no standard way to output to files yet...
VISIBLE "Hello" ON TehFilez
BTW #There isn't a standard way to append to files either...
MOAR VISIBLE "World" ON TehFilez
GIMMEH LINES TehLinez OUTTA TehFilez
I HAS A SecondLine ITZ 1 IN MAH TehLinez
VISIBLE SecondLine
O NOES
VISIBLE "OH NOES!!!"
KTHXBYE
Python 3
with open('fileio.txt', 'w') as f:
f.write('hello')
with open('fileio.txt', 'a') as f:
f.write('\nworld')
with open('fileio.txt') as f:
s = f.readlines()[1]
print(s)
Clarifications
readlines() returns a list of all the lines in the file.
Therefore, the invokation of readlines() results in reading each and every line of the file.
In that particular case it's fine to use readlines() because we have to read the entire file anyway (we want its last line).
But if our file contains many lines and we just want to print its nth line, it's unnecessary to read the entire file.
Here are some better ways to get the nth line of a file in Python: What substitutes xreadlines() in Python 3?.
What is this with statement?
The with statement starts a code block where you can use the variable f as a stream object returned from the call to open().
When the with block ends, python calls f.close() automatically.
This guarantees the file will be closed when you exit the with block no matter how or when you exit the block
(even if you exit it via an unhandled exception). You could call f.close() explicitly, but what if your code raises an exception and you don't get to the f.close() call? That's why the with statement is useful.
You don't need to reopen the file before each operation. You can write the whole code inside one with block.
with open('fileio.txt', 'w+') as f:
f.write('hello')
f.write('\nworld')
s = f.readlines()[1]
print(s)
I used three with blocks to emphsize the difference between the three operations:
write (mode 'w'), append (mode 'a'), read (mode 'r', the default).
Brain***k
,------------------------------------------------>,------------------------------------------------>,------------------------------------------------>[-]+++++++++>[-]+++++++++>[-]+++++++++<<<<<[>>>>>>+>>>+<<<<<<<<<-]>>>>>>>>>[<<<<<<<<<+>>>>>>>>>-]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]<<<<<<<[>>>>>>+>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]>>[-]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]<<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<<<->>>->>>>>[-]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]<<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>][-]<<<<<<<[>>>>>+>>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<<->>>->>>>[-]<<<<<<<[>>>>>+>>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>][-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<->>>->>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<[-]+<[-]+<<<<<<[>>>>>>[-]<<<<<<[-]]>>>>>>[[-]+<<<<<[>>>>>[-]<<<<<[-]]>>>>>[[-]+<<<<[>>>>[-]<<<<[-]]>>>>[[-]+<<<[>>>[-]<<<[-]]>>>[[-]+<<[>>[-]<<[-]]>>[[-]+<[>[-]<[-]]>[[-]+++++++++++++++++++++++++++++++++++++++++++++++++.-...>[-]<[-]]<>[-]]<<>>[-]]<<<>>>[-]]<<<<>>>>[-],------------------------------------------------>,------------------------------------------------>,------------------------------------------------>[-]+++++++++>[-]+++++++++>[-]+++++++++<<<<<[>>>>>>+>>>+<<<<<<<<<-]>>>>>>>>>[<<<<<<<<<+>>>>>>>>>-]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]<<<<<<<[>>>>>>+>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]>>[-]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]<<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<<<->>>->>>>>[-]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]<<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>][-]<<<<<<<[>>>>>+>>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<<->>>->>>>[-]<<<<<<<[>>>>>+>>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]<<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>][-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<->>>->>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<[-]+<[-]+<<<<<<[>>>>>>[-]<<<<<<[-]]>>>>>>[[-]+<<<<<[>>>>>[-]<<<<<[-]]>>>>>[[-]+<<<<[>>>>[-]<<<<[-]]>>>>[[-]+<<<[>>>[-]<<<[-]]>>>[[-]+<<[>>[-]<<[-]]>>[[-]+<[>[-]<[-]]>[[-]+++++++++++++++++++++++++++++++++++++++++++++++++.-...>[-]<[-]]<>[-]]<<>>[-]]<<<>>>[-]]<<<<>>>>[-]]<<<<<>>>>>[-]]<<<<<<>>>>>>>[<<<<<<<<[>>>>>>+>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]>[-]++++++++++<<+<<<<<<+>>>>>>>>>>>[-]<<<<<[>>>+>>+<<<<<-]>>>>>[<<<<<+>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<->>->>>[-]<<<<<[>>>+>>+<<<<<-]>>>>>[<<<<<+>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<[-]+<[>[-]<[-]]>[[-]+>[<[-]>[-]]<[<<<<<<<[-]<+>>>>>>>>[-]]><[-]]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]>[-]++++++++++>>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<->>>->>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<[-]+<<[>>[-]<<[-]]>>[[-]+>[<[-]>[-]]<[<<<<<<<<[-]<+>>>>>>>>>[-]]><[-]]<<<<<<<<<++++++++++++++++++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++++++++++++++++++++++.>>>>>>>>[-]]]<<<<<>>>>>[-]]<<<<<<>>>>>>>[<<<<<<<<[>>>>>>+>+<<<<<<<-]>>>>>>>[<<<<<<<+>>>>>>>-]>[-]++++++++++<<+<<<<<<+>>>>>>>>>>>[-]<<<<<[>>>+>>+<<<<<-]>>>>>[<<<<<+>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<->>->>>[-]<<<<<[>>>+>>+<<<<<-]>>>>>[<<<<<+>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<[-]+<[>[-]<[-]]>[[-]+>[<[-]>[-]]<[<<<<<<<[-]<+>>>>>>>>[-]]><[-]]<<<<<<<<[>>>>>>+>>+<<<<<<<<-]>>>>>>>>[<<<<<<<<+>>>>>>>>-]>[-]++++++++++>>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<->>>->>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<[-]+<<[>>[-]<<[-]]>>[[-]+>[<[-]>[-]]<[<<<<<<<<[-]<+>>>>>>>>>[-]]><[-]]<<<<<<<<<++++++++++++++++++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++++++++++++++++++++++.>>>>>>>>[-]]
COBOL
Since nobody else did......
IDENTIFICATION DIVISION.
PROGRAM-ID. WriteDemo.
AUTHOR. Mark Mullin.
* Hey, I don't even have a cobol compiler
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT StudentFile ASSIGN TO "STUDENTS.DAT"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD TestFile.
01 TestData.
02 LineNum PIC X.
02 LineText PIC X(72).
PROCEDURE DIVISION.
Begin.
OPEN OUTPUT TestFile
DISPLAY "This language is still around."
PERFORM GetFileDetails
PERFORM UNTIL TestData = SPACES
WRITE TestData
PERFORM GetStudentDetails
END-PERFORM
CLOSE TestFile
STOP RUN.
GetFileDetails.
DISPLAY "Enter - Line number, some text"
DISPLAY "NXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
ACCEPT TestData.
Haskell
main :: IO ()
main = let filePath = "fileio.txt" in
do writeFile filePath "hello"
appendFile filePath "\nworld"
fileLines <- readFile filePath
let secondLine = (lines fileLines) !! 1
putStrLn secondLine
If you just want to read/write a file:
main :: IO ()
main = readFile "somefile.txt" >>= writeFile "someotherfile.txt"
D
module d_io;
import std.stdio;
void main()
{
auto f = File("fileio.txt", "w");
f.writeln("hello");
f.writeln("world");
f.open("fileio.txt", "r");
f.readln;
auto s = f.readln;
writeln(s);
}
Ruby
PATH = 'fileio.txt'
File.open(PATH, 'w') { |file| file.puts "hello" }
File.open(PATH, 'a') { |file| file.puts "world" }
puts line = File.readlines(PATH).last
C#
string path = "fileio.txt";
File.WriteAllLines(path, new[] { "hello"}); //Will end it with Environment.NewLine
File.AppendAllText(path, "world");
string secondLine = File.ReadLines(path).ElementAt(1);
Console.WriteLine(secondLine);
File.ReadLines(path).ElementAt(1) is .Net 4.0 only, the alternative is File.ReadAllLines(path)[1] which parses the whole file into an array.
ANSI C
#include <stdio.h>
#include <stdlib.h>
int /*ARGSUSED*/
main(char *argv[0], int argc) {
FILE *file;
char buf[128];
if (!(file = fopen("fileio.txt", "w")) {
perror("couldn't open for writing fileio.txt");
exit(1);
}
fprintf(file, "hello");
fclose(file);
if (!(file = fopen("fileio.txt", "a")) {
perror("couldn't opened for appening fileio.txt");
exit(1);
}
fprintf(file, "\nworld");
fclose(file);
if (!(file = fopen("fileio.txt", "r")) {
perror("couldn't open for reading fileio.txt");
exit(1);
}
fgets(buf, sizeof(buf), file);
fgets(buf, sizeof(buf), file);
fclose(file);
puts(buf);
return 0;
}
Shell Script (UNIX)
#!/bin/sh
echo "hello" > fileio.txt
echo "world" >> fileio.txt
LINE=`sed -ne2p fileio.txt`
echo $LINE
Actually the sed -n "2p" part prints the second line, but the question asks for the second line to be stored in a variable and then printed, so... :)
x86 Assembler (NASM) on Linux
I haven't touched asm in 7 years, so I had to use google a bit to hack this together, but still, it works ;) I know it's not 100% correct, but hey :D
OK, it doesn't work. sorry bout this. while it does print world in the end, it doesn't print it from the file, but from the ecx which is set on line 27.
section .data
hello db 'hello',10
helloLen equ $-hello
world db 'world',10
worldLen equ $-world
helloFile db 'hello.txt'
section .text
global _start
_start:
mov eax,8
mov ebx,helloFile
mov ecx,00644Q
int 80h
mov ebx,eax
mov eax,4
mov ecx, hello
mov edx, helloLen
int 80h
mov eax,4
mov ecx, world
mov edx, worldLen
int 80h
mov eax,6
int 80h
mov eax,5
mov ebx,helloFile
int 80h
mov eax,3
int 80h
mov eax,4
mov ebx,1
int 80h
xor ebx,ebx
mov eax,1
int 80h
References used:
http://www.cin.ufpe.br/~if817/arquivos/asmtut/quickstart.html
http://bluemaster.iu.hio.no/edu/dark/lin-asm/syscalls.html
http://www.digilife.be/quickreferences/QRC/LINUX%20System%20Call%20Quick%20Reference.pdf
JavaScript - node.js
First, lots of nested callbacks.
var fs = require("fs");
var sys = require("sys");
var path = "fileio.txt";
fs.writeFile(path, "hello", function (error) {
fs.open(path, "a", 0666, function (error, file) {
fs.write(file, "\nworld", null, "utf-8", function () {
fs.close(file, function (error) {
fs.readFile(path, "utf-8", function (error, data) {
var lines = data.split("\n");
sys.puts(lines[1]);
});
});
});
});
});
A little bit cleaner:
var writeString = function (string, nextAction) {
fs.writeFile(path, string, nextAction);
};
var appendString = function (string, nextAction) {
return function (error, file) {
fs.open(path, "a", 0666, function (error, file) {
fs.write(file, string, null, "utf-8", function () {
fs.close(file, nextAction);
});
});
};
};
var readLine = function (index, nextAction) {
return function (error) {
fs.readFile(path, "utf-8", function (error, data) {
var lines = data.split("\n");
nextAction(lines[index]);
});
};
};
var writeToConsole = function (line) {
sys.puts(line);
};
writeString("hello", appendString("\nworld", readLine(1, writeToConsole)));
Common Lisp
(defun main ()
(with-open-file (s "fileio.txt" :direction :output :if-exists :supersede)
(format s "hello"))
(with-open-file (s "fileio.txt" :direction :io :if-exists :append)
(format s "~%world")
(file-position s 0)
(loop repeat 2 for line = (read-line s nil nil) finally (print line))))
PowerShell
sc fileio.txt 'hello'
ac fileio.txt 'world'
$line = (gc fileio.txt)[1]
$line
Shell Script
Here's a shell script using just builtin commands, rather than invoking external commands such as sed or tail as previous responses have done.
#!/bin/sh
echo hello > fileio.txt # Print "hello" to fileio.txt
echo world >> fileio.txt # Print "world" to fileio.txt, appending
# to what is already there
{ read input; read input; } < fileio.txt
# Read the first two lines of fileio.txt,
# storing the second in $input
echo $input # Print the contents of $input
When writing significant shell scripts, it is advisable to use builtins as much as possible, since spawning a separate process can be slow; from a quick test on my machine, the sed solution is about 20 times slower than using read. If you're going to call sed once, as in this case, it doesn't really matter much, as it will execute more quickly than you can notice, but if you're going to execute it hundreds or thousands of times, it can add up.
For those unfamiliar with the syntax, { and } execute a list of commands in the current shell environment (as opposed to ( and ) which create a subshell; we need to be operating in the current shell environment, so we can use the value of the variable later). We need to group the commands together in order to have them both operate on the same input stream, created by redirecting from fileio.txt; if we simply ran read < fileio.txt; read input < fileio.txt, we would just get the first line, as the file would be closed and re-opened between the two commands. Due to an idiosyncrasy of shell syntax ({ and } are reserved words, as opposed to metacharacters), we need to separate the { and } from the rest of the commands with spaces, and terminate the list of commands with a ;.
The read builtin takes as an argument the names of variables to read into. It consumes a line of input, breaks the input by whitespace (technically, it breaks it according to the contents of $IFS, which defaults to a space character, where a space character means split it on any of space, tab, or newline), assigns each word to the variable names given in order, and assigns the remainder of the line to the last variable. Since we're just supplying one variable, it just puts the whole line in that variable. We reuse the $input variable, since we don't care what's on the first line (if we're using Bash we could just not supply a variable name, but to be portable, you must always supply at least one name).
Note that while you can read lines one at a time, like I do here, a much more common pattern would be to wrap it in a while loop:
while read foo bar baz
do
process $foo $bar $baz
done < input.txt
Clojure
(use '[clojure.java.io :only (reader)])
(let [file-name "fileio.txt"]
(spit file-name "hello")
(spit file-name "\nworld" :append true)
(println (second (line-seq (reader file-name)))))
Or equivalently, using the threading macro -> (also known as the paren remover):
(use '[clojure.java.io :only (reader)])
(let [file-name "fileio.txt"]
(spit file-name "hello")
(spit file-name "\nworld" :append true)
(-> file-name reader line-seq second println))
F#
let path = "fileio.txt"
File.WriteAllText(path, "hello")
File.AppendAllText(path, "\nworld")
let secondLine = File.ReadLines path |> Seq.nth 1
printfn "%s" secondLine
BASIC
I haven't used BASIC in almost 10 years, but this question gave me a reason to quickly brush up my knowledge. :)
OPEN "fileio.txt" FOR OUTPUT AS 1
PRINT #1, "hello"
PRINT #1, "world"
CLOSE 1
OPEN "fileio.txt" FOR INPUT AS 1
LINE INPUT #1, A$
LINE INPUT #1, A$
CLOSE 1
PRINT A$
Objective-C
NSFileHandle *fh = [NSFileHandle fileHandleForUpdatingAtPath:#"fileio.txt"];
[[NSFileManager defaultManager] createFileAtPath:#"fileio.txt" contents:nil attributes:nil];
[fh writeData:[#"hello" dataUsingEncoding:NSUTF8StringEncoding]];
[fh writeData:[#"\nworld" dataUsingEncoding:NSUTF8StringEncoding]];
NSArray *linesInFile = [[[NSString stringWithContentsOfFile:#"fileio.txt"
encoding:NSUTF8StringEncoding
error:nil] stringByStandardizingPath]
componentsSeparatedByString:#"\n"];
NSLog(#"%#", [linesInFile objectAtIndex:1]);
Perl
#!/usr/bin/env perl
use 5.10.0;
use utf8;
use strict;
use autodie;
use warnings qw< FATAL all >;
use open qw< :std :utf8 >;
use English qw< -no_match_vars >;
# and the last shall be first
END { close(STDOUT) }
my $filename = "fileio.txt";
my($handle, #lines);
$INPUT_RECORD_SEPARATOR = $OUTPUT_RECORD_SEPARATOR = "\n";
open($handle, ">", $filename);
print $handle "hello";
close($handle);
open($handle, ">>", $filename);
print $handle "world";
close($handle);
open($handle, "<", $filename);
chomp(#lines = <$handle>);
close($handle);
print STDOUT $lines[1];
R:
cat("hello\n", file="fileio.txt")
cat("world\n", file="fileio.txt", append=TRUE)
line2 = readLines("fileio.txt", n=2)[2]
cat(line2)
PHP
<?php
$filePath = "fileio.txt";
file_put_contents($filePath, "hello");
file_put_contents($filePath, "\nworld", FILE_APPEND);
$lines = file($filePath);
echo $lines[1];
// closing PHP tags are bad practice in PHP-only files, don't use them
Java
import java.io.*;
import java.util.*;
class Test {
public static void main(String[] args) throws IOException {
String path = "fileio.txt";
File file = new File(path);
//Creates New File...
try (FileOutputStream fout = new FileOutputStream(file)) {
fout.write("hello\n".getBytes());
}
//Appends To New File...
try (FileOutputStream fout2 = new FileOutputStream(file,true)) {
fout2.write("world\n".getBytes());
}
//Reading the File...
try (BufferedReader fin = new BufferedReader(new FileReader(file))) {
fin.readLine();
System.out.println(fin.readLine());
}
}
}
C++
#include <limits>
#include <string>
#include <fstream>
#include <iostream>
int main() {
std::fstream file( "fileio.txt",
std::ios::in | std::ios::out | std::ios::trunc );
file.exceptions( std::ios::failbit );
file << "hello\n" // << std::endl, not \n, if writing includes flushing
<< "world\n";
file.seekg( 0 )
.ignore( std::numeric_limits< std::streamsize >::max(), '\n' );
std::string input_string;
std::getline( file, input_string );
std::cout << input_string << '\n';
}
or somewhat less pedantically,
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
int main() {
fstream file( "fileio.txt", ios::in | ios::out | ios::trunc );
file.exceptions( ios::failbit );
file << "hello" << endl
<< "world" << endl;
file.seekg( 0 ).ignore( 10000, '\n' );
string input_string;
getline( file, input_string );
cout << input_string << endl;
}
Go
package main
import (
"os"
"bufio"
"log"
)
func main() {
file, err := os.Open("fileio.txt", os.O_RDWR | os.O_CREATE, 0666)
if err != nil {
log.Exit(err)
}
defer file.Close()
_, err = file.Write([]byte("hello\n"))
if err != nil {
log.Exit(err)
}
_, err = file.Write([]byte("world\n"))
if err != nil {
log.Exit(err)
}
// seek to the beginning
_, err = file.Seek(0,0)
if err != nil {
log.Exit(err)
}
bfile := bufio.NewReader(file)
_, err = bfile.ReadBytes('\n')
if err != nil {
log.Exit(err)
}
line, err := bfile.ReadBytes('\n')
if err != nil {
log.Exit(err)
}
os.Stdout.Write(line)
}
Erlang
Probably not the most idiomatic Erlang, but:
#!/usr/bin/env escript
main(_Args) ->
Filename = "fileio.txt",
ok = file:write_file(Filename, "hello\n", [write]),
ok = file:write_file(Filename, "world\n", [append]),
{ok, File} = file:open(Filename, [read]),
{ok, _FirstLine} = file:read_line(File),
{ok, SecondLine} = file:read_line(File),
ok = file:close(File),
io:format(SecondLine).
Emacs Lisp
Despite what some people say Emacs is mainly a text editor [1]. So while Emacs Lisp can be used to solve all kinds of problems it is optimized towards the needs of a text editor. Since text editors (obviously) have quite specific needs when it comes to how files are handled this affects what file related functionality Emacs Lisp offers.
Basically this means that Emacs Lisp does not offer functions to open a file as a stream, and read it part by part. Likewise you can't append to a file without loading the whole file first. Instead the file is completely [2] read into a buffer [3], edited and then saved to a file again.
For must tasks you would use Emacs Lisp for this is suitable and if you want to do something that does not involve editing the same functions can be used.
If you want to append to a file over and over again this comes with a huge overhead, but it is possible as demonstrated here. In practice you normally finish making changes to a buffer whether manually or programmatically before writing to a file (just combine the first two s-expressions in the example below).
(with-temp-file "file"
(insert "hello\n"))
(with-temp-file "file"
(insert-file-contents "file")
(goto-char (point-max))
(insert "world\n"))
(with-temp-buffer
(insert-file-contents "file")
(next-line)
(message "%s" (buffer-substring (point) (line-end-position))))
[1] At least I would not go as far as calling it an OS; an alternative UI yes, an OS no.
[2] You can load only parts of a file, but this can only be specified byte-wise.
[3] A buffer is both a datatype in someways similar to a string as well as the "thing you see while editing a file". While editing a buffer is displayed in a window but buffers do not necessarily have to be visible to the user.
Edit: If you want to see the text being inserted into the buffer you obviously have to make it visible, and sleep between actions. Because Emacs normally only redisplays the screen when waiting for user input (and sleeping ain't the same as waiting for input) you also have to force redisplay. This is necessary in this example (use it in place of the second sexp); in practice I never had to use `redisplay' even once - so yes, this is ugly but ...
(with-current-buffer (generate-new-buffer "*demo*")
(pop-to-buffer (current-buffer))
(redisplay)
(sleep-for 1)
(insert-file-contents "file")
(redisplay)
(sleep-for 1)
(goto-char (point-max))
(redisplay)
(sleep-for 1)
(insert "world\n")
(redisplay)
(sleep-for 1)
(write-file "file"))
Windows Batch Files - Version #2
#echo off
echo hello > fileio.txt
echo world >> fileio.txt
set /P answer=Insert:
echo %answer% >> fileio.txt
for /f "skip=1 tokens=*" %%A in (fileio.txt) do echo %%A
To explain that last horrible looking for loop, it assumes that there is only hello (newline) world in the file. So it just skips the first line and echos only the second.
Changelog
2 - Opps, must of misread the requirements or they changed on me. Now reads last line from file
Scala:
Using standard library:
val path = "fileio.txt"
val fout = new FileWriter(path)
fout write "hello\n"
fout.close()
val fout0 = new FileWriter(path, true)
fout0 write "world\n"
fout0.close()
val str = Source.fromFile(path).getLines.toSeq(1)
println(str)
Using Josh Suereth's Scala-ARM Library:
val path = "fileio.txt"
for(fout <- managed(new FileWriter(path)))
fout write "hello\n"
for(fout <- managed(new FileWriter(path, true)))
fout write "world\n"
val str = Source.fromFile(path).getLines.toSeq(1)
println(str)
Since many people have used the same file descriptor to write the two strings, I'm also including that way in my answer.
Using standard library:
val path = "fileio.txt"
val fout = new FileWriter(path)
fout write "hello\n"
fout write "world\n"
fout.close()
val str = Source.fromFile(path).getLines.toSeq(1)
println(str)
Using Josh Suereth's Scala-ARM Library:
val path = "fileio.txt"
for(fout <- managed(new FileWriter(path))){
fout write "hello\n"
fout write "world\n"
}
val str = Source.fromFile(path).getLines.toSeq(1)
println(str)
Groovy
new File("fileio.txt").with {
write "hello\n"
append "world\n"
println secondLine = readLines()[1]
}