路漫漫其修远兮
吾将上下而求索

第12章总结

12.1 

可以使用下面的进行从命令行标准输入
func main() {
	var firstName, lastName string
	fmt.Println("input")
	fmt.Scanln(&firstName, &lastName)
	//fmt.Scanf("%s %s", &firstName, &lastName)
	fmt.Printf("%s, %s", firstName, lastName)

}
Scanln 扫描来自标准输入的文本,将空格分隔的值依次存放到后续的参数内,直到碰到换行
D:\go\test2\main>go run test.go
input
andy bob tome
andy, bob


使用bufio来进行读取
var inputReader *bufio.Reader
var input string
var err error

func main() {
	inputReader = bufio.NewReader(os.Stdin)
	fmt.Println("input")
	input, err := inputReader.ReadString('\n')
	if err == nil {
		fmt.Println("input", input)
	}
}

inputReader 是一个指向 bufio.Reader 的指针。inputReader := bufio.NewReader(os.Stdin) 这行代码,将会创建一个读取器,并将其与标准输入绑定。
bufio.NewReader() 构造函数的签名为:func NewReader(rd io.Reader) *Reader


12.2 

文件使用指向 os.File 类型的指针来表示的,也叫做文件句柄。我们在前面章节使用到过标准输入 os.Stdin 和标准输出 os.Stdout,他们的类型都是 *os.File
变量 inputFile 是 *os.File 类型的。该类型是一个结构,表示一个打开文件的描述符(文件句柄)。然后,使用 os 包里的 Open 函数来打开一个文件。
通过使用 bufio 包提供的读取器(写入器也类似),如上面程序所示,我们可以很方便的操作相对高层的 string 对象,而避免了去操作比较底层的字节。
接着,我们在一个无限循环中使用 ReadString('\n') 或 ReadBytes('\n') 将文件的内容逐行(行结束符 '\n')读取出来。
func main() {
	inputFile, inputError := os.Open("abc.txt")
	if inputError != nil {
		fmt.Printf("an error occurd \n" +
			"does file exist?\n")
		return
	}
	defer inputFile.Close()

	inputReader := bufio.NewReader(inputFile)
	for {
		inputString, readerError := inputReader.ReadString('\n')
		fmt.Printf("%s", inputString)
		if readerError == io.EOF {
			return
		}
	}
}


将文件读取,然后写入另外文件
func main() {
	inputFile := "abc.txt"
	outputFile := "bcd.txt"
	buf, err := ioutil.ReadFile(inputFile)
	if err != nil {
		fmt.Printf("%s\n", err)
	}
	fmt.Printf("%s\n", string(buf))

	err =ioutil.WriteFile(outputFile, buf, 0664)
	if err != nil {
		panic (err.Error())
	}
}


2) 带缓冲的读取
在很多情况下,文件的内容是不按行划分的,或者干脆就是一个二进制文件。在这种情况下,ReadString()就无法使用了,我们可以使用 bufio.Reader 的 Read(),
它只接收一个参数:

buf := make([]byte, 1024)
...
n, err := inputReader.Read(buf)
if (n == 0) { break}
变量 n 的值表示读取到的字节数.

注意: path 包里包含一个子包叫 filepath,这个子包提供了跨平台的函数,用于处理文件名和路径。例如 Base() 函数用于获得路径中的最后一个元素
(不包含后面的分隔符):

import "path/filepath"
filename := filepath.Base(path)


写文件
outputFile, outputError := os.OpenFile("output.dat", os.O_WRONLY|os.O_CREATE, 0666)
if outputError != nil {
    fmt.Printf("An error occurred with file opening or creation\n")
    return  
}
defer outputFile.Close()

outputWriter := bufio.NewWriter(outputFile)
outputString := "hello world!\n"

for i:=0; i<10; i++ {
    outputWriter.WriteString(outputString)
}
outputWriter.Flush()
除了文件句柄,我们还需要 bufio 的 Writer。我们以只写模式打开文件 output.dat,如果文件不存在则自动创建:
可以看到,OpenFile 函数有三个参数:文件名、一个或多个标志(使用逻辑运算符“|”连接),使用的文件权限。

我们通常会用到以下标志:
os.O_RDONLY:只读
os.O_WRONLY:只写
os.O_CREATE:创建:如果指定文件不存在,就创建该文件。
os.O_TRUNC:截断:如果指定文件已存在,就将该文件的长度截为0。
在读文件的时候,文件的权限是被忽略的,所以在使用 OpenFile 时传入的第三个参数可以用0。而在写文件时,不管是 Unix 还是 Windows,都需要使用 0666。


12.3 

文件拷贝
func main() {
	CopyFile("bcd.txt", "abc.txt")
	fmt.Println("Copy done!")
}

func CopyFile(dstName, srcName string) (written int64, err error){
	src, err := os.Open(srcName)
	if err != nil {
		return
	}
	defer src.Close()

	dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		return
	}
	defer dst.Close()

	return io.Copy(dst, src)
}


12.4 
os 包中有一个 string 类型的切片变量 os.Args,用来处理一些基本的命令行参数,它在程序启动后读取命令行输入的参数。
func main() {
	who := "a "
	if len(os.Args) > 1 {
		who += strings.Join(os.Args[1:]," ")
	}
	fmt.Println(who)
}

D:\go\test2\main>go run test.go andy bob
a andy bob

os.Args[0] 放的是程序本身的名字


12.9 

数据结构 --> 指定格式 = 序列化 或 编码(传输之前)
指定格式 --> 数据格式 = 反序列化 或 解码(传输之后)

这是一个简短的 JSON 片段:
{
    "Person": {
        "FirstName": "Laura",
        "LastName": "Lynn"
    }
}

未经允许不得转载:江哥架构师笔记 » 第12章总结

分享到:更多 ()

评论 抢沙发

评论前必须登录!