Go 语言 の 日志(读写文件和时间)
文章目录
对切片的操作,是值类型的,对 map 的操作是指针类型的。对传值的效果也是一样的。
go 对文件的操作
对文件进行操作的时候,,如果是一行一行的读,建议使用 bufio
来实现。
- 如果只是读,可以只使用 Open 这个方法,如果要是写就不行了。
- 如果要写,使用
openfile
做个函数,使用指定的模式打开该文件。
package main
import (
"bufio"
"fmt"
"io"
"os"
)
func main() {
fileObej, err := os.Open("./test.go") // 读取文件,可以使用相对路径
if err != nil {
fmt.Println("open test.go failed") // 打印文件的时候出错了
return
}
defer fileObej.Close() // 最后要关闭文件夹
// 使用 buf 来读
read := bufio.NewReader(fileObej) // 使用buf 来读
for { // 一行一行的来读
line, err := read.ReadString('\n') // 注意是字符
if err == io.EOF {
fmt.Println("文件读完了")
break
}
if err != nil {
fmt.Println("文件有错误", err) // 把错误打印出来
}
fmt.Println(line)
}
}
对整个文件进行操作
package main
import (
"fmt"
"io/ioutil"
)
func main() {
contents, err := ioutil.ReadFile("./test.go")
if err != nil {
fmt.Println("文件输出有错", err)
return
}
fmt.Println(string(contents)) // 把二进制的文件转换成字符串
}
写数据操作
package main
import (
"fmt"
"os"
)
func main() {
fileObej, err := os.OpenFile("./test.txt", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 02) // 可写或者创建
if err != nil {
fmt.Println("打开文件有错误", err)
return
}
defer fileObej.Close() // 先检查打开错误,再说关闭的事情
fileObej.WriteString("你好,我是test 文件夹")
}
time包
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
fmt.Println(t)
fmt.Println(t.Year()) // 年
fmt.Println(t.Hour()) // 小时
fmt.Println(t.Format("2006-01-02")) // 格式化输出,是按照go语言发明的时间声明的。
fmt.Println("解析格式")
fmt.Println(time.Parse("2006-01-02", "2008-15-4"))
fmt.Println("打印时间戳")
fmt.Println(t.Unix()) //时间戳
fmt.Println(t.UnixNano()) // 毫秒的时间戳
fmt.Println("暂停五秒")
// 暂停1分钟再打印
time.Sleep(5 * time.Second)
// 把时间戳变成年
fmt.Println("把时间戳再转变成年")
tm := time.Unix(1618114441, 0)
fmt.Println(tm) // 把年转换回来
fmt.Println("时间相加")
fmt.Println(t.Add(time.Hour * 24))
fmt.Println("定时器")
v := 0
// 打印计时器(本质上是通道)
timer := time.Tick(time.Second) // 一秒执行一次
for t := range timer {
v++
if v > 10 {
break
}
fmt.Println(t)
}
}
// 输出
2021-04-11 14:03:35.7623396 +0800 CST m=+0.004965801
2021
14
2021-04-11
解析格式
0001-01-01 00:00:00 +0000 UTC parsing time "2008-15-4": month out of range
打印时间戳
1618121015
1618121015762339600
暂停一分钟
exit status 3221225786
D:\GoCode\src\pengzhao.xyz>go run test.go
2021-04-11 14:04:08.9291022 +0800 CST m=+0.003156501
2021
14
2021-04-11
解析格式
0001-01-01 00:00:00 +0000 UTC parsing time "2008-15-4": month out of range
打印时间戳
1618121048
1618121048929102200
暂停五秒
把时间戳再转变成年
2021-04-11 12:14:01 +0800 CST
时间相加
2021-04-12 14:04:08.9291022 +0800 CST m=+86400.003156501
定时器
2021-04-11 14:04:14.9676934 +0800 CST m=+6.041747701
2021-04-11 14:04:15.9563958 +0800 CST m=+7.030450101
2021-04-11 14:04:16.9524537 +0800 CST m=+8.026508001
2021-04-11 14:04:17.9617691 +0800 CST m=+9.035823401
2021-04-11 14:04:18.9694327 +0800 CST m=+10.043487001
2021-04-11 14:04:19.9576334 +0800 CST m=+11.031687701
2021-04-11 14:04:20.9564513 +0800 CST m=+12.030505601
2021-04-11 14:04:21.95758 +0800 CST m=+13.031634301
2021-04-11 14:04:22.9633547 +0800 CST m=+14.037409001
2021-04-11 14:04:23.9623826 +0800 CST m=+15.036436901
3.按照时区解析格式
package main
import (
"fmt"
"time"
)
func main() {
loc, err := time.LoadLocation("Asia/Shanghai")
if err != nil {
fmt.Println("如果时间解析错误", err)
return
}
fmt.Println(loc)
t, err := time.ParseInLocation("2006-01-02 15:04:05", "2021-04-11 14:50:00", loc)
if err != nil {
fmt.Println("时间解析格式错误", err)
return
}
fmt.Println(t)
}
// 时间输出
Asia/Shanghai
2021-04-11 14:50:00 +0800 CST
4.日志完整操作
4.1 日志文件的需求分析
-
往不同的地方输出日志
-
日志要分级别:
- Debug
- Trace
- Info
- Warning
- Error
- Fatal
-
日志要支持开关控制:能够在调试的过程中,输出
debug
,在其他的似乎,输出error
-
完整的日记记录,应该包括 日志时间:文件夹的名字,日志级别,日志的信息。
-
日志文件要切割。
4.2 log自带的日志库
每过两秒打印一次日志记录
for {
log.Println("这是一条日志")
time.Sleep(2 * time.Second)
}
// 输出
2021/04/11 15:05:48 这是一条日志
2021/04/11 15:05:50 这是一条日志
2021/04/11 15:05:52 这是一条日志
2021/04/11 15:05:54 这是一条日志
2021/04/11 15:05:56 这是一条日志
4.3 使用自带的日志库打印到文件里
package main
import (
"fmt"
"log"
"os"
"time"
)
func main() {
// 先找到一个文件打开
fileObj, err := os.OpenFile("./xx.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0)
if err != nil {
fmt.Println("打开文件失败", err)
return
}
log.SetOutput(fileObj) // 把他写到打开的文件里
for {
log.Println("再试一下") // 此时不是打印到终端,而是打印到文件里
time.Sleep(2 * time.Second)
}
}
自己手写一个日记记录文件
package mylog
import (
"errors"
"fmt"
"strings"
"time"
)
type LogLevel uint32
const (
DEBUG LogLevel = iota
TRACE
INFO
WARNING
UNKNOWN
)
// 往日记库里写东西
type Logger struct {
level LogLevel
}
// 解析传入的函数
func parseLogLevel(s string) (LogLevel, error) { // 返回错误和logger
// 先把传入的字符串导成大写
s = strings.ToLower(s) // 全部都转成小写
switch s {
case "debug":
return DEBUG, nil //
case "trace":
return TRACE, nil //
case "warning":
return WARNING, nil //
default:
err := errors.New("无效的日志级别")
return UNKNOWN, err
}
}
// 构造函数
func New(s string) *Logger {
level, err := parseLogLevel(s)
if err != nil {
panic(err) // 用了 panic 就不用 return 了
}
return &Logger{
level: level, // 把声明好好的 level 返回回去
}
}
// 使用开关
func (l *Logger) enabled(loglevel LogLevel) bool {
if l.level > loglevel {
return true
} else {
return false
}
}
// 打印看看
func (i *Logger) Debug(msg string) {
if i.enabled(DEBUG) {
// 打时间
now := time.Now()
fmt.Println("时间", now.Format("2006-01-02 T: 15:04:05"))
// 打印信息
fmt.Println(msg)
}
}
func (i *Logger) TRACE(msg string) {
row := time.Now()
fmt.Println(msg, row)
}
func (i *Logger) Info(msg string) {
fmt.Println(msg)
}
func (i *Logger) Warn(msg string) {
fmt.Println(msg)
}
main 函数
package main
import (
"fmt"
"path"
"runtime"
"pengzhao.xyz/mylog"
)
func main() {
fmt.Println("*****开始****")
pc, file, line, ok := runtime.Caller(0) // 函数调用的堆栈信息,在main函数里调用,就要用0
if !ok {
fmt.Println("打开文件有问题")
}
fmt.Println(file) // 文件名
// 拿到最下面的一层
fmt.Println(path.Base(file)) // 只把最后一层的文件名拿出来
fmt.Println(line) // 第几行
// 拿到文件名
funcName := runtime.FuncForPC(pc).Name() // 函数名
fmt.Println(funcName)
log := mylog.New("debug")
log.Debug("有点小错误")
}
// 输出
*****开始****
D:/GoCode/src/pengzhao.xyz/test.go
test.go
13
main.main
字符串和其他格式之间的转换
func main() {
i := "25"
// 把字符串解析成int
m, err := strconv.ParseInt(i, 10, 64) // 解析成10进制,64位
if err != nil {
fmt.Println(err)
return
}
// 把字符串解析层 float 类型
f1 := "25.8"
c, _:= strconv.ParseFloat(f1, 10)
fmt.Println(c)
// 把字符串解析成 bool
b1 := "true"
b, _ := strconv.ParseBool(b1)
fmt.Println(b)
fmt.Printf("%d,%T", m, m)
fmt.Println(m)
}