long blogs

进一步有进一步惊喜


  • Home
  • Archive
  • Tags
  •  

© 2025 long

Theme Typography by Makito

Proudly published with Hexo

go-file

Posted at 2020-06-25 golang 

Golang 文件夹相关操作

文件夹的创建

创建一级文件夹

如果文件夹已经存在会返回错误

1
2
3
4
5
6
// 在所在盘的根目录创建文件夹,如果运行在F盘,则在F盘创建 F://oneLevelDir
err := os.Mkdir("/oneLevelDir",0666)
// 在特定盘符创建文件夹
err = os.Mkdir("D://oneLevelDir",0666)
// 在当前目录下创建文件夹
err = os.Mkdir("oneLevelDir",0666)
创建多级文件夹

想要在不同的位置创建文件夹,和创建一级文件夹一致。

1
err := os.MkdirAll("multiDir1/second/third",0666)

文件(夹)重命名

文件夹重命名
1
err := os.Rename("oneLevelDir","oneLevelDir2")
文件重命名
1
err := os.Rename("test.txt","test2.txt")

移动文件(夹)

可以用Rename完成文件移动操作,将test2.txt移到oneLevelDir2中

1
err := os.Rename("test2.txt","oneLevelDir2/test2.txt")

复制文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 源文件
srcFile,err := os.Open("oneLevelDir2/test2.txt")
defer srcFile.Close()
if err != nil {
fmt.Println(err)
return
}

// 目标文件
desFile,err := os.OpenFile("test2.txt",os.O_CREATE|os.O_TRUNC|os.O_RDWR,0666)
if err != nil {
fmt.Println(err)
return
}
n,err := io.Copy(desFile,srcFile)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(n)

复制文件夹可以先创建文件夹,然后再遍历复制文件便可。

查询文件夹

方法一使用file.Readdir(n)获得信息
1
2
3
4
5
6
7
8
9
10
// 当前文件夹
file,err := os.Open("./")
// 获得当前文件夹下文件列表
var n int = 0
// n <=0获得全部文件,n>0获得相应个数的文件
fileList,err := file.Readdir(n)
// 输出文件夹信息
for _,f := range fileList {
fmt.Printf("%v\t\t%v\t\t%v\t\t%v\t\t%v\n",f.Name(),f.IsDir(),f.Size(),f.Mode(),f.ModTime())
}
只获得文件夹名
1
fileNameList,err := file.Readdirnames(0)

返回文件名字符串数组

删除文件(夹)

删除文件
1
err :=os.Remove("test2.txt")
删除文件夹

删除文件夹及文件夹下所有数据

1
err = os.RemoveAll("oneLevelDir2")

Golang 文件相关操作

新建文件

使用OpenFile中os.OCREATE选项可以创建文件

1
_,err := os.OpenFile("test2.txt",os.O_CREATE,0666)

读取文件

方法一

可以读取出全部的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
file,err := os.Open("test2.txt")
if err != nil {
fmt.Println(err)
return
}
data := make([]byte,0)
buffer := make([]byte,1024)
for {
n,err := file.Read(buffer)
if err == io.EOF {
// 读取完成
break
}
// 循环赋值
for i:=0;i<n;i++{
data = append(data,buffer[i])
}
}
fmt.Printf("%q",string(data))
方法二

使用bufio带缓冲读取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
file,err := os.Open("test2.txt")
if err != nil {
fmt.Println(err)
return
}
// 带缓冲的
r:= bufio.NewReader(file)
sb := strings.Builder{}
for true {
tmp,err := r.ReadString('\n')
if err == io.EOF {
// 如果最后一行数据没有\n符也要加进去
sb.WriteString(tmp)
break
}
sb.WriteString(tmp)
}
fmt.Printf("%q",sb.String())

注意 当出现EOF错误时只是说明读取的行没有’\n’结尾,通常是文件末尾,但是还有一种情况是最后一行末尾没有换行符。这一行的数据也要存进去。

方法三

使用ioutil工具包

1
2
3
4
5
6
data,err := ioutil.ReadFile("test2.txt")
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%q",string(data))

ReadFile()实现是使用os.Open()函数加上bytes.Buffer.ReadFrom()函数完成

写入文件

方法一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
file,err := os.OpenFile("test3.txt",os.O_RDWR|os.O_CREATE|os.O_TRUNC,0666)
if err != nil {
return
}
defer file.Close()
// n,err := file.Write([]byte("Welcome"))
n,err := file.WriteString("Hello World \r\n")
if err != nil {
return
}
fmt.Println(n)
// 偏移插入,覆盖写入
_,err = file.WriteAt([]byte("Append"),6)
if err != nil {
return
}
方法二

带缓冲的写入

1
2
3
4
5
6
7
8
 file,err := os.OpenFile("test3.txt",os.O_RDWR|os.O_CREATE|os.O_TRUNC,0666)
if err != nil {
return
}
defer file.Close()
r := bufio.NewWriter(file)
r.WriteString("Hello,World")
r.Flush()
方法三

ioutil.WriteFile写入

1
err := ioutil.WriteFile("test3.txt",[]byte("Hello,World3"),0666)

实现方法是OpenFile()写入.golang官方实现如下,和方法一类似,但是更好。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func WriteFile(filename string, data []byte, perm os.FileMode) error {
f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
if err != nil {
return err
}
n, err := f.Write(data)
if err == nil && n < len(data) {
err = io.ErrShortWrite
}
if err1 := f.Close(); err == nil {
err = err1
}
return err
}

总结

File默认实现了io.Writer和io.Reader的接口。所以bufio可以直接传file过去。

1
2
3
type Reader interface {
Read(p []byte) (n int, err error)
}
1
2
3
type Writer interface {
Write(p []byte) (n int, err error)
}

其它小技巧

string转Reader
1
w := strings.NewReader("Hello World")

用途,当需要流转换的时候。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 转换成Reader对象
r1 := strings.NewReader("Hello World")
// 使用bufio读出数据
br := bufio.NewReader(r1)
data := ""
for true {
s,err := br.ReadString('\n')
if err == io.EOF {
data += s
break
}
data += s
}
fmt.Printf("%q",data)

Share 

 Previous post: go-reflect Next post: go-rpc 

© 2025 long

Theme Typography by Makito

Proudly published with Hexo