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('\n') //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('\n'); err == nil || err == io.EOF; line, err = reader.ReadString('\n') {
		s.WriteString(line)
		if err == io.EOF {
			break
		}
	}
	*/

	if _, err := writer.WriteString(s); err == nil {
		writer.Flush()
	} else {
		fmt.Println(err.Error())
	}

}
posted on 2018-09-01 15:14  scala  阅读(202)  评论(0编辑  收藏  举报