package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
var inFile, outFile *os.File
if inFile, err := os.Open("in.txt"); inFile == nil { //inFile 是指针类型可以赋值nil (1)
fmt.Println(err.Error())
inFile = os.Stdin
}
defer inFile.Close()
if outFile, err := os.OpenFile("out.txt", os.O_RDWR, 0766); err != nil {
fmt.Println(outFile) ////这里必须用一下outFile , 否则go编译器扯淡报错outFile未使用过,或者也可以象(1)那样反过来不判断err而判断另一个不空
fmt.Println(err.Error())
outFile = os.Stdout
}
defer outFile.Close()
reader, writer := bufio.NewReader(inFile), bufio.NewWriter(outFile)
var s bytes.Buffer
for {
line, err := reader.ReadString('
') //nil 只能赋值给指针和引用类型,报错 can not convert nil to string
if err != nil && err != io.EOF { //真出错了,而不是到结尾了
break
}
//bytes.Buffer 类似于 java 中的 StringBuilder 处理大量字符串连接非常好
s.WriteString(line)
//字符串是值类型不能有其他值,也不能用空字符串标识到了文件结尾,这会和空行混淆
if err == io.EOF { //到结尾了
break
}
}
/*
//另一种感觉更清晰的写法
for line, err := reader.ReadString('
'); err == nil || err == io.EOF; line, err = reader.ReadString('
') {
s.WriteString(line)
if err == io.EOF {
break
}
}
*/
if _, err := writer.WriteString(s); err == nil {
writer.Flush()
} else {
fmt.Println(err.Error())
}
}