Go语言的处理文件

使用ioutil包读写文件

读取文件

标准库提供了ioutil包,能够快速执行众多涉及读写文件的操作。

读取一个文件并将其内容打印到终端,程序清单如下:

package main

import (
	"fmt"
	"io/ioutil"
	"log"
)


func main() {
	fileBytes, err:=ioutil.ReadFile("main.txt")
	if err!=nil{
		log.Fatal(err)
	}
	fileString:=string(fileBytes)
	fmt.Println(fileString)
}

如存在的文件,看到被打印出来的文件内容。如不存在的文件,运行结果如下:

2022/01/27 14:05:04 open example.txt: no such file or directory
exit status 1

创建文件

ioutil包提供了用于创建文件的便利函数WriteFile。这个函数设计用于将数据写入文件,但也可使用它来创建文件。函数WriteFile接受一个文件名、要写入文件的数据以及应用于文件的权限。

Go语言使用UNIX权限的数字表示法,很多用于处理文件的函数都将权限值作为参数。

文件权限
符号表示法数字表示法说明
----------0000无权限
-rwx------0700只有所有者能够读取、写入和执行
-rwxrwx---0770所有者及其所在的用户组能够读取、写入和执行
-rwxrwxrwx0777所有人能能够读取、写入和执行
---x--x--x0111所有人都能够执行
--w--w--w-0222所有人都能够写入
--wx-wx-wx0333所有人都能够写入和执行
-r--r--r--0444所有人都能够读取
-r-xr-xr-x0555所有人都能够读取和执行
-rw-rw-rw-0666所有人都能够读取和写入
-rwxr------740所有人能够读取、写入和执行,而所有者所在的用户组能够读取

在UNIX型系统中,文件的默认权限为0644,即所有者能够读取和写入,而其它人只能读取。

在文件系统中创建了一个文件,并将其权限设置为0644,程序清单如下:

package main

import (
	"io/ioutil"
	"log"
)


func main() {
	b:=make([]byte,0)
	err:=ioutil.WriteFile("example.txt",b,0644)
	if err!=nil{
		log.Fatal(err)
	}
}

运行结果:如不存在文件,将创建新的一个空文件example.txt,并给它设置指定的权限。输入ls -l,结果如下:

-rw-r--r--  1 douxiaobo  staff        0  1 27 14:24 example.txt

写入文件

将文件字符串写入文件,程序清单如下:

package main

import (
	"io/ioutil"
	"log"
)


func main() {
	s:="Hello World"
	err:=ioutil.WriteFile("example.txt",[]byte(s),0644)
	if err!=nil{
		log.Fatal(err)
	}
}

运行结果:如不存在文件,将会创建新文件,而且有内容“Hello World”。

列出目录的内容

要处理文件系统中的文件,必须知道目录结构。ioutil包提代了便利函数ReadDir,它接受以字符串方式指定的目录名,并返回一个列表,其它包含按文件名排序的文件。文件名的类型为FileInfo,包含如下信息:

Name:文件的名称。

Size:文件的长度,单位为字节。

Mode:用二进制位表示的权限。

ModTime:文件最后一个被修改的时间。

IsDir:文件是否是目录。

Sys:底层数据源。

列出目录中的文件及其权限,程序清单如下:

package main

import (
	"fmt"
	"io/ioutil"
	"log"
)


func main() {
	files,err:=ioutil.ReadDir(".")
	if err!=nil{
		log.Fatal(err)
	}
	for _,file:=range files{
		fmt.Println(file.Mode(),file.Name())
	}
}

运行结果如下:

-rw-r--r-- example.txt
-rwxr-xr-x main
-rw-r--r-- main.go
-rw-r--r-- main.txt
-rw-r--r-- main1.txt
-rw-r--r-- temperature.go
-rw-r--r-- temperature_test.go

复制文件

将文件的内容复制到一个新文件中,程序清单如下:

package main

import (
	"log"
	"os"
	"io"
)


func main() {
	from, err:=os.Open("./example.txt")
	if err!=nil{
		log.Fatal(err)
	}
	defer from.Close()

	to,err:=os.OpenFile("./example_cpy.txt",os.O_RDWR|os.O_CREATE,0666)
	if err!=nil{
		log.Fatal(err)
	}
	defer to.Close()

	_,err=io.Copy(to,from)
	if err!=nil{
		log.Fatal(err)
	}
}

运行结果,成功复制到另一个文件。

删除文件

删除文件,程序清单如下:

package main

import (
	"log"
	"os"
)


func main() {
	err:=os.Remove("./example_cpy.txt")
	if err!=nil{
		log.Fatal(err)
	}
}

运行结果:已经删除example_cpy.txt。

使用文件来管理配置

使用JSON文件存储配置,程序清单如下:

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
)
type Config struct{
	Name string		`json:"name"`
	Awake bool		`json:"awake"`
	Hungry bool		`json:"hungry"`
}
func main() {
	f,err:=ioutil.ReadFile("config.json")
	if err!=nil{
		log.Fatal(err)
	}
	c:=Config{}
	err=json.Unmarshal(f,&c)
	if err!=nil{
		log.Fatal(err)
	}
	fmt.Printf("%+v\n",c)
}

运行结果:没有json文件,无法试一下运行结果。

使用TOML文件

TOML(Tom's Obvious, Minimal Language)是一种专为存储配置文件而设计的格式。JSON是为序列化数据而设计。

使用TOML文件来存储配置,程序清单如下:

package main

import (
	"fmt"
	"log"
	"github.com/BurntSushi/toml"
)
type Config struct{
	Name string
	Awake bool
	Hungry bool
}
func main() {
	c:=Config{}
	_,err:=toml.DecodeFile("example.toml",&c)
	if err!=nil{
		log.Fatal(err)
	}
	fmt.Printf("%+v\n",c)
}

运行结果如下:(本人不清楚)

{Name: Awake:false Hungry:false}

文件操作:

func Mkdir(name string, perm FileMode) error 创建名称为name的目录,权限设置是perm。

func MkdirAll(path string, perm FileMode) error 根据path创建多级子目录。

func Remove(name string) error 删除名称为name的目录,当目录下有文件或者其它目录时会出错。

func RemoveAll(path string) error根据path删除多级子目录,如果path是单个名称,那么该目录下的子目录全部删除。

代码如下:

package main

import (
	"fmt"
	"os"
)

func main() {
	os.Mkdir("goDir", 0777)
	os.MkdirAll("goDir/test1/test2", 0777)
	err := os.Remove("goDir")
	if err != nil {
		fmt.Println(err)
	}
	os.RemoveAll("goDir")
}

运行结果如下:

remove goDir: The directory is not empty.

创建文件与查看状态:

1、新建文件

1)func Create(name string)(file *File, err Error)

根据提供的文件名创建新的文件,返回一个文件对象,默认权限是0666的文件,返回的文件对象是可读写的。

2)func NewFile(fd uintptr, name string) *File

根据文件描述符创建相应的文件,返回一个文件对象。

2、新建文件夹

func MkdirAll(path string, perm FileMode) error

path表示目录名及子目录,perm表示目录权限,error的值为nil表示创建成功无异常,如果目录已经存在不会执行操作。

3、文件/文件夹状态

func Stat(name string) (FileInfo, error)

如果没有错误将返回描述命名文件的FileInfo。

代码如下:

package main

import (
	"fmt"
	"log"
	"os"
)

var (
	newFile  *os.File
	fileInfo os.FileInfo
	err      error
	path     = "test/test2/"
	fileName = "demo"
	filePath = path + fileName
)

func main() {
	//创建文件夹
	err = os.MkdirAll(path, 0777)
	if err != nil {
		fmt.Printf("%s", err)
	} else {
		fmt.Println("成功创建目录")
	}

	//创建空白文件
	newFile, err = os.Create((filePath))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(newFile)
	newFile.Close()

	//查看文件的信息,如果文件不存在,则返回错误
	fileInfo, err = os.Stat(filePath)
	if err != nil && os.IsNotExist(err) {
		log.Fatal("文件不存在。")
	} else {
		log.Fatal(err)
	}
	fmt.Println("文件名称:", fileInfo.Name())
	fmt.Println("文件大小:", fileInfo.Size())
	fmt.Println("文件权限:", fileInfo.Mode())
	fmt.Println("最后修改时间:", fileInfo.ModTime())
	fmt.Println("是否是文件夹:", fileInfo.IsDir())
	fmt.Printf("系统接口类型:%T\n", fileInfo.Sys())
	fmt.Printf("系统信息:%+v\n\n", fileInfo.Sys())
}

运行结果如下:(不对)

成功创建目录
&{0xc00007c780}
2022/02/21 16:49:01 <nil>
exit status 1

重命名与移动

func Rename(oldpath, newpath string) error

代码如下:

package main

import (
	"log"
	"os"
)

func main() {
	originalPath := "test.txt"
	newPath := "test2.txt"
	err := os.Rename(originalPath, newPath)
	if err != nil {
		log.Fatal(err)
	}
}

运行结果如下:(无文件)如有文件,不会出现下面运行结果。

2022/02/21 17:06:05 rename test.txt test2.txt: The system cannot find the file specified.
exit status 1

打开与关闭

代码如下:

package main

import (
	"log"
	"os"
)

var (
	file     *os.File
	fileInfo os.FileInfo
	err      error
	dirPath  = "test/test2/"
	fileName = "demo"
	filePath = dirPath + fileName
)

func main() {
	file, err := os.Open(dirPath)
	if err != nil {
		log.Fatal(err)
	}
	buf := make([]byte, 1024)
	for {
		n, _ := file.Read(buf)
		if 0 == n {
			break
		}
		os.Stdout.Write(buf[:n])
	}
	file.Close()
	file, err = os.OpenFile(dirPath, os.O_APPEND, 0666)
	if err != nil {
		log.Fatal(err)
	}
	file.Close()
}

运行结果如下:

2022/03/02 20:56:25 open test/test2/: no such file or directory
exit status 1

func Open(name string)(file *File, err Error):该方法打开一个名称为name的文件,但用的是只读方式,内部实现其实是调用了为OpenFile()函数。

func OpenFile(name string, flag int, perm uint32) (file *File, err Error):打开名称为name的文件,flag是打开的方式,包括只读、读写等,perm是权限。

删除与截断

代码如下:

package main

import (
	"log"
	"os"
)

func main() {
	err := os.Remove("test.txt")
	if err != nil {
		log.Fatal(err)
	}
}

运行结果如下:

2022/03/07 14:39:29 remove test.txt: The system cannot find the file specified.
exit status 1

截断函数用于处理文件大小,代码如下:

package main

import (
	"log"
	"os"
)

func main() {
	err := os.Truncate("test.txt", 100)
	if err != nil {
		log.Fatal(err)
	}
}

运行结果如下:

读写文件

1、复制文件

代码如下:

package main

import (
	"io"
	"log"
	"os"
)

var (
	newFile  *os.File
	fileInfo os.FileInfo
	err      error
	path     = "test/test2/"
	fileName = "demo"
	filePath = path + fileName
)

func main() {
	//打开原始文件
	originalFile, err := os.Open(filePath)
	if err != nil {
		log.Fatal(err)
	}
	defer originalFile.Close()
	//创建新的文件作为目标文件
	newFile, err := os.Create(filePath + "_copy")
	if err != nil {
		log.Fatal(err)
	}
	defer newFile.Close()
	//从源文件中复制字节到目标文件
	bytesWritten, err := io.Copy(newFile, originalFile)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("文件已复制,大小 %d bytes。", bytesWritten)
	//将文件内容flush到硬盘中
	err = newFile.Sync()
	if err != nil {
		log.Fatal(err)
	}
}

运行结果如下:

2022/03/07 15:01:07 文件已复制,大小 0 bytes。

2、跳转函数

代码如下:

package main

import (
	"fmt"
	"log"
	"os"
)

var (
	newFile  *os.File
	err      error
	path     = "test/test2/"
	fileName = "demo"
	filePath = path + fileName
)

func main() {
	file, _ := os.Open(filePath)
	defer file.Close()

	//偏离位置,可以是正数也可以是负数
	var offset int64 = 5

	//用来计算offset的初始位置
	//0=文件开始位置
	//1=当前位置
	//2=文件结尾处
	whence := 0

	newPosition, err := file.Seek(offset, whence)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("移动到位置5:", newPosition)
	//从当前位置回退两字节
	newPosition, err = file.Seek(-2, 1)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("从当前位置退回两字节:", newPosition)
	//使用下面的方式得到当前的位置
	currentPosition, err := file.Seek(0, 1)
	fmt.Println("当前位置:", currentPosition)
	//转到文件开始处
	newPosition, err = file.Seek(0, 0)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("转到文件开始位置(0,0):", newPosition)
}

运行结果如下:

移动到位置5: 5
从当前位置退回两字节: 3
当前位置: 3
转到文件开始位置(0,0): 0

Seek()函数的特点类似于鼠标光标的定位,指定位置之后可以执行复制、剪切、粘贴等操作。

3、写入函数

func (file *File) Write(b []byte) (n int, err Error) 写入byte类型的信息到文件。

func (file *File) WriteAt(b []byte, off int64) (n int, err Error) 在指定位置开始写入byte类型的信息。

func (file *File) WriteString(s string)(ret int, err Error) 写入string信息到文件。

代码如下:

package main

import (
	"log"
	"os"
)

var (
	newFile  *os.File
	err      error
	dirPath  = "test/test2/"
	fileName = "demo"
	filePath = dirPath + fileName
)

func main() {
	//可写方式打开文件
	file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()
	//将字节写入文件中
	file.Write([]byte("写入字节。\r\n"))
	//将字符串写入文件中
	file.WriteString("写入字符串。\r\n")
	//打印文件内容
	file, err = os.Open(filePath)
	if err != nil {
		log.Fatal(err)
	}
	buf := make([]byte, 1024)
	for {
		n, _ := file.Read(buf)
		if 0 == n {
			break
		}
		os.Stdout.Write(buf[:n])
	}
	file.Close()
}

运行结果如下:(与书上不一样,上下相反)

写入字节。
写入字符串。

权限控制

代码如下:

package main

import (
	"log"
	"os"
)

var (
	file     *os.File
	err      error
	dirPath  = "test/test2/"
	fileName = "demo"
	filePath = dirPath + fileName
)

func main() {
	//测试写权限
	file, err := os.OpenFile(filePath, os.O_WRONLY, 0666)
	if err != nil && os.IsPermission(err) {
		log.Fatal("错误:没有写入权限。")
	} else if os.IsNotExist(err) {
		log.Fatal("错误:文件不存在。")
	} else {
		log.Fatal(err)
	}
	file.Close()
	//测试读权限
	file, err = os.OpenFile(filePath, os.O_RDONLY, 0666)
	if err != nil && os.IsPermission(err) {
		log.Fatal("错误:没有读取权限。")
	} else if os.IsNotExist(err) {
		log.Fatal("错误:文件不存在。")
	} else {
		log.Fatal(err)
	}
	file.Close()
}

运行结果如下:

2022/03/09 14:18:24 <nil>
exit status 1

代码如下:只有Linux下编写代码。

package main

import (
	"fmt"
	"log"
	"os"
	"time"
)

var (
	file     *os.File
	fileInfo os.FileInfo
	err      error
	dirPath  = "test/test2/"
	fileName = "demo"
	filePath = dirPath + fileName
)

func main() {
	//使用Linux风格改变文件权限
	err := os.Chmod(filePath, 0777)
	if err != nil {
		log.Println(err)
	}
	//改变文件所有者
	err = os.Chown(filePath, os.Getuid(), os.Getgid())
	if err != nil {
		log.Println(err)
	}
	//查看文件信息
	fileInfo, err = os.Stat(filePath)
	if err != nil {
		if os.IsNotExist(err) {
			log.Fatal("文件不存在。")
		}
		log.Fatal(err)
	}
	fmt.Println("最后修改时间:", fileInfo.ModTime())
	//改变时间戳
	twoDaysFromNow := time.Now().Add(48 * time.Hour)
	LastAccessTime := twoDaysFromNow
	LastModifyTime := twoDaysFromNow
	err = os.Chtimes(filePath, LastAccessTime, LastModifyTime)
	if err != nil {
		log.Println(err)
	}
}

运行结果如下:

2022/03/09 14:29:20 chown test/test2/demo: not supported by windows
最后修改时间: 2022-03-07 15:53:52.9906496 +0800 CST

文件链接

代码如下:

package main

import (
	"fmt"
	"log"
	"os"
)

var (
	newFile  *os.File
	fileInfo os.FileInfo
	err      error
	dirPath  = "test/test2/"
	fileName = "demo"
	filePath = dirPath + fileName
)

func main() {
	//创建一个硬链接
	//创建后同一个文件内容会有两个文件名,改变一个文件的内容会影响另一个
	//删除和重命名不会影响另一个
	hardLink := filePath + "h1"
	err := os.Link(filePath, hardLink)
	if err != nil {
		log.Println(err)
	}
	fmt.Println("创建硬链接")
	//创建一个软链接
	softLink := filePath + "s1"
	err = os.Symlink(fileName, softLink)
	if err != nil {
		log.Println(err)
	}
	fmt.Println("创建软链接")
	/*Lstat返回一个文件的信息,但是当文件是一个较链接时,它返回软链接的信息,而不是引用的文件的信息*/
	//Symlink在Windows中不工作
	fileInfo, err := os.Lstat(softLink)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("链接信息:%+v", fileInfo)
	//改变软链接的拥有得不会影响原始文件
	err = os.Lchown(softLink, os.Getuid(), os.Getgid())
	if err != nil {
		log.Fatal(err)
	}
}

运行结果如下:

创建硬链接
2022/03/09 14:58:07 symlink demo test/test2/demos1: A required privilege is not held by the client.
创建软链接
2022/03/09 14:58:07 CreateFile test/test2/demos1: The system cannot find the file specified.
exit status 1

XML处理

1、解析XML

func Unmarshal(data []byte, v interface{} error

data接收的是XML数据流,v是需要输出的结构,定义为interface,也就是可以把XML转换为任意格式。

代码如下:

package main

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"os"
)

type Recurlyservers struct {
	XMLName     xml.Name `xml:"servers"`
	Version     string   `xml:"version,attr"`
	Svs         []server `xml:"server"`
	Description string   `xml:",innerxml"`
}

type server struct {
	XMLName    xml.Name `xml:"server"`
	ServerName string   `xml:"serverName"`
	ServerIP   string   `xml:"serverIP"`
}

func main() {
	file, err := os.Open("servers.xml")
	if err != nil {
		fmt.Print("error: %v", err)
		return
	}
	defer file.Close()
	data, err := ioutil.ReadAll(file)
	if err != nil {
		fmt.Printf("error: %v", err)
		return
	}
	v := Recurlyservers{}
	err = xml.Unmarshal(data, &v)
	if err != nil {
		fmt.Printf("error: %v", err)
		return
	}
	fmt.Println(v)
}

运行结果如下:

error: %vopen servers.xml: The system cannot find the file specified.

2、生成XML

func Marshal(v interface{}) ([]byte,error)

func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)

代码如下:

package main

import (
	"encoding/xml"
	"fmt"
	"os"
)

type Servers struct {
	XMLName xml.Name `xml:"servers"`
	Version string   `xml:"version,attr"`
	Svs     []server `xml:"server"`
}

type server struct {
	ServerName string `xml:"serverName"`
	ServerIP   string `xml:"serverIP"`
}

func main() {
	v := &Servers{Version: "1"}
	v.Svs = append(v.Svs, server{"Local_Web", "172.0.0.1"})
	v.Svs = append(v.Svs, server{"Local_DB", "172.0.0.2"})
	output, err := xml.MarshalIndent(v, " ", "  ")
	if err != nil {
		fmt.Printf("error: %v\n", err)
	}
	os.Stdout.Write([]byte(xml.Header))
	os.Stdout.Write(output)
}

运行结果如下:

<?xml version="1.0" encoding="UTF-8"?>
 <servers version="1">
   <server>
     <serverName>Local_Web</serverName>
     <serverIP>172.0.0.1</serverIP>
   </server>
   <server>
     <serverName>Local_DB</serverName>
     <serverIP>172.0.0.2</serverIP>
   </server>
 </servers>

JSON处理

1、解析JSON

一种是解析到结构体,另一种是解析到接口。

func Unmarshal(data []byte, v interface{}) error

代码如下:

package main

import (
	"encoding/json"
	"fmt"
)

type Server struct {
	ServerName string
	ServerIP   string
}

type Serverslice struct {
	Servers []Server
}

func main() {
	var s Serverslice
	str := `{"servers":[{"serverName":"Local_Web","serverIP":"172.0.0.1"},{"serverName":"Local_DB","serverIP":"172.0.0.2"}]}`
	json.Unmarshal([]byte(str), &s)
	fmt.Println(s)
}

运行结果如下:

{[{Local_Web 172.0.0.1} {Local_DB 172.0.0.2}]}

2、生成JSON

func Marshal(v interface{}) ([]byte, error)

代码如下:

package main

import (
	"encoding/json"
	"fmt"
)

type Server struct {
	ServerName string
	ServerIP   string
}

type Serverslice struct {
	Servers []Server
}

func main() {
	var s Serverslice
	s.Servers = append(s.Servers, Server{ServerName: "Local_Web", ServerIP: "172.0.0.1"})
	s.Servers = append(s.Servers, Server{ServerName: "Local_DB", ServerIP: "172.0.0.2"})
	b, err := json.Marshal(s)
	if err != nil {
		fmt.Println("json err:", err)
	}
	fmt.Println(string(b))
}

运行结果如下:

{"Servers":[{"ServerName":"Local_Web","ServerIP":"172.0.0.1"},{"ServerName":"Local_DB","ServerIP":"172.0.0.2"}]}

日志记录

1、Logrus

安装logrus的命令行如下:

go get -u github.com/sirupsen/logrus

运行结果如下:

package golang.org/x/sys/unix: unrecognized import path "golang.org/x/sys/unix": https fetch: Get "https://golang.org/x/sys/unix?go-get=1": dial tcp 142.251.42.241:443: i/o timeout

代码如下:

package main

import (
	log "github.com/Sirupsen/logrus"
)

func main() {
	log.WithFields(log.Fields{
		"tool": "pen",
	}).Info("This is pen.")
}

运行结果如下:

../github.com/Sirupsen/logrus/terminal_check_bsd.go:6:8: cannot find package "golang.org/x/sys/unix" in any of:
	/usr/local/go/src/golang.org/x/sys/unix (from $GOROOT)
	/Users/douxiaobo/go/src/golang.org/x/sys/unix (from $GOPATH)

代码如下:

package main

import (
	"os"

	log "github.com/Sirupsen/logrus"
)

func init() {
	//日志格式化为JSON而不是默认的ASCII
	log.SetFormatter(&log.JSONFormatter{})

	//输出stdout而不是默认的stderr,也可以是一个文件
	log.SetOutput(os.Stdout)

	//只记录严重或以上警告
	log.SetLevel(log.WarnLevel)
}

func main() {
	log.WithFields(log.Fields{
		"tool":  "pen",
		"price": 10,
	}).Info("The pen price is 10 dollars.")

	contextLogger := log.WithFields(log.Fields{
		"common": "这是一个字段",
		"other":  "其他你想记录的东西",
	})
	contextLogger.Info("此处会记录common和other字段")
}

运行结果如下:

../github.com/Sirupsen/logrus/terminal_check_bsd.go:6:8: cannot find package "golang.org/x/sys/unix" in any of:
	/usr/local/go/src/golang.org/x/sys/unix (from $GOROOT)
	/Users/douxiaobo/go/src/golang.org/x/sys/unix (from $GOPATH)

2、Seelog

安装Seelog的命令行如下:

go get -u github.com/cihub/seelog

运行结果如下:

# cd .; git clone -- https://github.com/cihub/seelog /Users/douxiaobo/go/src/github.com/cihub/seelog
Cloning into '/Users/douxiaobo/go/src/github.com/cihub/seelog'...
fatal: unable to access 'https://github.com/cihub/seelog/': LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 
package github.com/cihub/seelog: exit status 128

代码如下:

package main

import (
	log "github.com/cihub/seelog"
)

func main() {
	defer log.Flush()
	log.Info("你好,Seelog。")
}

运行结果如下:

tempCodeRunnerFile.go:4:2: cannot find package "github.com/cihub/seelog" in any of:
	/usr/local/go/src/github.com/cihub/seelog (from $GOROOT)
	/Users/douxiaobo/go/src/github.com/cihub/seelog (from $GOPATH)

运行结果如下:

main.go:4:2: cannot find package "github.com/cihub/seelog" in any of:
	/usr/local/go/src/github.com/cihub/seelog (from $GOROOT)
	/Users/douxiaobo/go/src/github.com/cihub/seelog (from $GOPATH)

压缩

1、打包与解包

代码如下:

package main

import (
	"archive/zip"
	"log"
	"os"
)

func main() {
	//创建一个打包文件
	outFile, err := os.Create("test.zip")
	if err != nil {
		log.Fatal(err)
	}
	defer outFile.Close()

	//使用zip包的创建函数zipWriter用于写入文件
	zipWriter := zip.NewWriter(outFile)

	//往打包文件中写文件
	var filesToArchive = []struct {
		name, Body string
	}{
		{"test.txt", "String contents of file"},
		{"test2.txt", "\x61\x62\x63\n"},
	}

	//下面将要打包的内容写入打包文件中,依次写入
	for _, file := range filesToArchive {
		fileWriter, err := zipWriter.Create(file.name)
		if err != nil {
			log.Fatal(err)
		}
		_, err = fileWriter.Write([]byte(file.Body))
		if err != nil {
			log.Fatal(err)
		}
	}
	
	//清理
	err = zipWriter.Close()
	if err != nil {
		log.Fatal(err)
	}
}

运行结果如下:

代码如下:

package main

import (
	"archive/zip"
	"io"
	"log"
	"os"
	"path/filepath"
)

func main() {
	zipReader, err := zip.OpenReader("test.zip")
	if err != nil {
		log.Fatal(err)
	}
	defer zipReader.Close()

	//遍历打包文件中的每一文件/文件夹
	for _, file := range zipReader.Reader.File {
		zippedFile, err := file.Open()
		if err != nil {
			log.Fatal()
		}
		defer zippedFile.Close()

		//指定提取的文件名
		//你可以指定全路径名或者一个前缀,这样可以把它们放在不同的文件夹中
		//这个例子使用打包文件中相同的文件名
		targetDir := "./"
		extractedFilePath := filepath.Join(
			targetDir,
			file.Name,
		)
		if file.FileInfo().IsDir() {
			//创建文件夹并设置同样的权限
			log.Println("正在创建目录:", extractedFilePath)
			os.MkdirAll(extractedFilePath, file.Mode())
		} else {
			//提取正常的文件
			log.Println("正在提取文件:", file.Name)
			outputFile, err := os.OpenFile(
				extractedFilePath,
				os.O_WRONLY|os.O_CREATE|os.O_TRUNC,
				file.Mode(),
			)
			if err != nil {
				log.Fatal(err)
			}
			defer outputFile.Close()

			//通过io.Copy简洁地复制文件内容
			_, err = io.Copy(outputFile, zippedFile)
			if err != nil {
				log.Fatal(err)
			}
		}
	}
}

运行结果如下:

2022/03/14 10:53:24 正在提取文件: test.txt
2022/03/14 10:53:24 正在提取文件: test2.txt

2、压缩与解压

代码如下:

package main

import (
	"compress/gzip"
	"log"
	"os"
)

func main() {
	outputFile, err := os.Create("test.txt.gz")
	if err != nil {
		log.Fatal(err)
	}
	gzipWriter := gzip.NewWriter(outputFile)
	defer gzipWriter.Close()

	_, err = gzipWriter.Write([]byte("Gophers rule!\n"))
	if err != nil {
		log.Fatal(err)
	}
	log.Println("已经压缩数据并写入文件。")
}

运行结果如下:

2022/03/14 17:01:05 已经压缩数据并写入文件。

代码如下:

package main

import (
	"compress/gzip"
	"io"
	"log"
	"os"
)

func main() {
	//打开一个gzip文件
	gzipFile, err := os.Open("test.txt.gz")
	if err != nil {
		log.Fatal(err)
	}
	gzipReader, err := gzip.NewReader(gzipFile)
	if err != nil {
		log.Fatal(err)
	}
	defer gzipReader.Close()

	//解压缩到一个writer,它是一个file writer
	outfileWriter, err := os.Create("unzipped.txt")
	if err != nil {
		log.Fatal(err)
	}
	defer outfileWriter.Close()

	//复制内容
	_, err = io.Copy(outfileWriter, gzipReader)
	if err != nil {
		log.Fatal()
	}
}

运行结果如下:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页
评论

打赏作者

DXB2021

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值