go 标准库 os 基础知识

fmt

文档 fmt

使用 fmt 输出一些东西,如果你想要自定义一些输出,fmt 提供了四种实现方式:

go 复制代码
type Formatter interface {
	Format(f State, verb rune)
}

type Stringer interface {
	String() string
}

type GoStringer interface {
	GoString() string
}

type error interface {
	Error() string
}

只要某个结构体实现了这些方法,就可以自定义输出了

当四个接口都实现时,输出的优先级为:

  1. 如果一个结构体实现了 Formatter 接口,将由该实现控制
  2. 如果一个结构体实现了 GoStringer 接口,将由该实现控制,不过这个需要配合 # 使用
  3. 如果一个结构体实现了 error 接口,将由该实现控制
  4. 如果一个结构体实现了 Stringer 接口,将由该实现控制
go 复制代码
func (p Person) String() string {
  return fmt.Sprintf("String: Name is %s, Age is %d", p.Name, p.Age)
}

func (p Person) Error() string {
  return fmt.Sprintf("Error: Name is %s, Age is %d", p.Name, p.Age)
}

func (p Person) Format(f fmt.State, verb rune) {
  switch verb {
  case 'u':
    fmt.Fprintf(f, "Format ToUpper: Name is %s, Age is %d", strings.ToUpper(p.Name), p.Age)
  case 'l':
    fmt.Fprintf(f, "Format ToLower: Name is %s, Age is %d", strings.ToLower(p.Name), p.Age)
  default:
    fmt.Fprintf(f, "Format Default: Name is %s, Age is %d", p.Name, p.Age)
  }
}

func (p Person) GoString() string {
  return fmt.Sprintf("GoString: Person{Name: \"%s\", Age: %d}", p.Name, p.Age)
}

对于 %v 来说有效的优先级为:Formatter > error > Stringer

go 复制代码
fmt.Printf("%v\n", person)

对于 %#v 来说有效的优先级为:Formatter > GoStringer

go 复制代码
fmt.Printf("%#v\n", person)

Formatter

Formatter 还可以自定义字符,比如 %u

go 复制代码
func (p Person) Format(f fmt.State, verb rune) {
  switch verb {
  case 'u':
    fmt.Fprintf(f, "Format ToUpper: Name is %s, Age is %d", strings.ToUpper(p.Name), p.Age)
  case 'l':
    fmt.Fprintf(f, "Format ToLower: Name is %s, Age is %d", strings.ToLower(p.Name), p.Age)
  default:
    fmt.Fprintf(f, "Format Default: Name is %s, Age is %d", p.Name, p.Age)
  }
}

将会命中 case 'u' 分支

go 复制代码
fmt.Printf("%u\n", person)

环境变量

go 通过 os.Getenv 可以获取到环境变量

go 复制代码
func main() {
  home := os.Getenv("HOME")
  fmt.Println("Home directory:", home)    // 获取 HOME 环境变量
}

命令行环境变量设置,不能设置已有的环境变量,比如 HOME

go 复制代码
UCCS="/home" go run .

func main() {
	home := os.Getenv("UCCS")
	fmt.Println("Home directory:", home)
}

设置临时环境比变量,在命令行输入时临时的,可以把这个命令写入到 ~/.bashrc

go 复制代码
export UCCS="/home"

文件读取

按行读取文件

go 复制代码
func main() {
	file, err := os.Open("example.csv")
	if err != nil {
		panic(err)
	}
	defer file.Close()

	reader := bufio.NewReader(file)
	for {
		line, _, err := reader.ReadLine()
		if err != nil {
			if err == io.EOF {    // 读到文件最后,err 为 EOF
				break
			}
			panic(err)
		}
		fmt.Println(string(line))
	}
}

os.Openos.OpenFile 的区别在于:os.Open 只读,os.OpenFile 可以指定读写权限,os.Open 封装了 os.OpenFile

os 文件操作:

  • os.O_TRUNC 会清空文件内容
  • os.O_APPEND 会在文件末尾追加内容
  • os.O_CREATE 会创建文件
  • os.O_RDONLY 只读
  • os.O_WRONLY 只写
  • os.O_RDWR 读写

用 seek 实现 append

seek 的第一个参数是偏移量,第二个参数是相对位置

  • 偏移量为 0 表示相对于当前位置
    • 偏移量不能传入很大的负数,否则会报错
  • 相对位置
    • io.SeekEnd 表示相对于文件末尾
    • io.SeekStart 表示相对于文件开头
    • io.SeekCurrent 表示相对于当前位置
go 复制代码
file.Seek(0, io.SeekEnd)

读取目录

ReadDir(-1) 读取所有文件,ReadDir(1) 读取一个文件

go 复制代码
file, _ := os.OpenFile("test", os.O_RDONLY, 0644)
dirEntries, _ := file.ReadDir(-1)
相关推荐
爱勇宝1 小时前
客户只想看个页面,我却做了一个静态演示发布系统
前端·javascript·后端
一个有理想的摸鱼选手1 小时前
(四)路书Agnet-综合天气距离交通节奏等多因素来编排旅行路线
前端·后端·gis
神奇的程序员1 小时前
在这个独属于ai的时代,我终究是被裁员了
前端·后端·面试
云边有个稻草人1 小时前
从单机工具到“云+端+服务”:KDMS数据库迁移工具如何支撑大型信创项目协同作战
后端
李广坤1 小时前
AgentScope Tool 热更新技术方案:不重启服务,实时管控 Agent 工具
后端·架构
ttwuai1 小时前
Go 后台接入 SSO 后菜单正常但接口 403,怎么排查权限链路?
开发语言·后端·golang
65岁退休Coder2 小时前
LangChain v1.3.4 笔记 - 08 MCP & 相关概念
后端·python·langchain
郑州光合科技余经理2 小时前
海外版多语言团购系统架构:主数据互通与核销边界
java·开发语言·前端·后端·系统架构·php·ai编程
vipxieliang3 小时前
ValidX 的 Date 和 DateTime vs JPA 的 Temporal 对比
java·后端
触底反弹3 小时前
🔥 从「为什么」到「怎么用」:TypeScript 类型约束与泛型完全指南
后端·面试·typescript