–
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" } }
–
评论前必须登录!
注册