在 io 包中最重要的是两个接口:Reader 和 Writer 接口。本章所提到的各种 IO 包,都跟这两个接口有关,也就是说,只要实现了这两个接口,它就有了 IO 的功能。
Reader 接口的定义如下:
type Reader interface {
Read(p []byte) (n int, err error)
}
示例代码:
/*********test.go*****************/
package main
import (
"fmt"
"io"
"os"
"strings"
"zshanjun/util"
)
func main() {
ReaderExample()
}
func ReaderExample() {
FOREND:
for {
readerMenu()
var ch string
fmt.Scanln(&ch)
var (
data []byte
err error
)
switch strings.ToLower(ch) {
case "1":
fmt.Println("请输入不多于9个字符,以回车结束:")
data, err = ReadFrom(os.Stdin, 11)
case "2":
file, err := os.Open(util.GetProjectRoot() + "/01.txt")
if err != nil {
fmt.Println("打开文件01.txt错误:", err)
continue
}
data, err = ReadFrom(file, 9)
file.Close()
case "3":
data, err = ReadFrom(strings.NewReader("from string"), 12)
case "4":
fmt.Println("暂未实现!")
case "b":
fmt.Println("返回上级菜单!")
break FOREND
case "q":
fmt.Println("程序退出!")
os.Exit(0)
default:
fmt.Println("输入错误!")
continue
}
if err != nil {
fmt.Println("数据读取失败,可以试试从其他来源读取!")
} else {
fmt.Printf("读取到的数据是:%s\n", data)
}
}
}
func ReadFrom(reader io.Reader, num int) ([]byte, error) {
p := make([]byte, num)
n, err := reader.Read(p)
if n > 0 {
return p[:n], nil
}
return p, err
}
func readerMenu() {
fmt.Println("")
fmt.Println("*****从不同来源读取数据*****")
fmt.Println("*****请选择数据源,请输入:*****")
fmt.Println("1 表示 标准输入")
fmt.Println("2 表示 普通文件")
fmt.Println("3 表示 从字符串")
fmt.Println("4 表示 从网络")
fmt.Println("b 返回上级菜单")
fmt.Println("q 退出")
fmt.Println("****************************")
}
/*******************util.go***********************/
// Copyright 2013 The StudyGolang Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// http://studygolang.com
// Author:polaris studygolang@gmail.com
package util
import (
"fmt"
"os"
"path"
"path/filepath"
"strings"
)
// 获得项目根目录
func GetProjectRoot() string {
binDir, err := executableDir()
if err != nil {
return ""
}
return path.Dir(binDir)
}
// 获得可执行程序所在目录
func executableDir() (string, error) {
pathAbs, err := filepath.Abs(os.Args[0])
if err != nil {
return "", err
}
return filepath.Dir(pathAbs), nil
}
func Welcome() {
fmt.Println("***********************************")
fmt.Println("*******欢迎来到Go语言中文网*******")
fmt.Println("***********************************")
}
// strings.Index的UTF-8版本
// 即 Utf8Index("Go语言中文网", "学习") 返回 4,而不是strings.Index的 8
func Utf8Index(str, substr string) int {
asciiPos := strings.Index(str, substr)
if asciiPos == -1 || asciiPos == 0 {
return asciiPos
}
pos := 0
totalSize := 0
reader := strings.NewReader(str)
for _, size, err := reader.ReadRune(); err == nil; _, size, err = reader.ReadRune() {
totalSize += size
pos++
// 匹配到
if totalSize == asciiPos {
return pos
}
}
return pos
}
登陆发表评论