• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

go语言文件操作

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

文件操作

字符串处理函数

字符串在开发中使用频率较高,我们经常需要对字符串进行拆分、判断等操作,可以借助Go标准库中的strings包快速达到处理字符串的目录。除ContainsJoinTrimReplace等我们学过的字符串处理函数之外,以下函数也常常会被用到。

字符串分割

func Split(s, sep string) []string
//功能:把s字符串按照sep分割,返回slice
参1:s,表示待拆分的字符串
参2:sep,表示分割符,该参数为string 类型
返回值:切片,存储拆分好的子串

示例代码:

fmt.Printf("%q\n", strings.Split("a,b,c", ","))
    fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a "))
    fmt.Printf("%q\n", strings.Split(" xyz ", ""))
    fmt.Printf("%q\n", strings.Split("", "Bernardo O\'Higgins"))
    //运行结果:
    //["a" "b" "c"]
    //["" "man " "plan " "canal panama"]
    //[" " "x" "y" "z" " "]
    //[""]

按空格拆分字符串

func Fields(s string) []string
//功能:去除s字符串的空格符,并且按照空格分割,返回slice
参1:s,表示待拆分的字符串
返回值:切片,存储拆分好的子串

示例代码:

 fmt.Printf("Fields are: %q", strings.Fields("  foo bar  baz   "))
  //运行结果:Fields are: ["foo" "bar" "baz"]

判断字符串后缀

func HasSuffix(s, suffix string) bool
功能:判断s字符串是否有后缀子串suffix
参1:s,表示待判定字符串
参2:suffix,表示前缀子串
返回值:true or false

示例代码:

fmt.Printf("%v\n", strings.HasSuffix("World Cup.png", ".png"))
    //运行结果:true

判断字符串前缀

func HasPrefix(s, prefix string) bool
功能:判断s字符串是否有前缀子串suffix
参1:s,表示待判定字符串
参2:prefix,表示前缀子串
返回值:true or false

示例代码:

 fmt.Printf("%v\n", strings.HasPrefix("World Cup.png", "world"))
    //运行结果:false

 

文件操作常用API

建立与打开文件

新建文件可以通过如下两个方法:

func Create(name string) (file *File, err Error)
根据提供的文件名创建新的文件,返回一个文件对象,默认权限是0666的文件,返回的文件对象是可读写的。
func main()  {
    f, err := os.Create("C:/itcast/test.txt")
    if err != nil {
        fmt.Println("Create err:", err)
        return
    }
    defer f.Close()

    fmt.Println("create successful")
}
View Code

通过如下两个方法来打开文件:

func Open(name string) (file *File, err Error)
func main()  {

    f, err := os.Open("C:/itcast/test.txt")
    if err != nil {
        fmt.Println("open err: ", err)
        return
    }
    defer f.Close()

    _, err = f.WriteString("hello world")
    if err != nil {
        fmt.Println("WriteString err: ", err)
        return
    }
    fmt.Println("open successful")
}
View Code

 

Open()是以只读权限打开文件名为name的文件,得到的文件指针file,只能用来对文件进行“读”操作。如果我们有“写”文件的需求,就需要借助Openfile函数来打开了。

 

func OpenFile(name string, flag int, perm uint32) (file *File, err Error)

OpenFile()可以选择打开name文件的读写权限。这个函数有三个默认参数:

1name,表示打开文件的路径。可使用相对路径 绝对路径

参2flg,表示读写模式,常见的模式有:

O_RDONLY(只读模式), O_WRONLY(只写模式), O_RDWR(可读可写模式), O_APPEND(追加模式)。|  O_CREATE (当有此参数,必须指定 参数3)  重要的是如果读取目录的话只能指定O_RDONLY模式!!!!

3perm,表权限取值范围(0-7),表示如下:

0:没有任何权限

1:执行权限(如果是可执行文件,是可以运行的)

2:写权限

3: 权限与执行权限

4:读权限

5: 读权限与执行权限

6: 读权限与写权限

7: 读权限,写权限,执行权限

 

func main()  {
    f, err := os.OpenFile("C:/itcast/test.txt", os.O_RDWR | os.O_CREATE, 0600)  // 777--rwx rwx rwx
    if err != nil {
        fmt.Println("OpenFile err: ", err)
        return
    }
    defer f.Close()
    f.WriteString("hello world12345...")

    fmt.Println("open successful")
}
View Code

 

关闭文件函数:

func (f *File) Close() error

写文件

1.按照字符串写:

func (file *File) WriteString(s string) (ret int, err Error)
写入string信息到文件
f.
WriteString
返回实际写出的字节数

windows: 回车、换行。 \r\n

Linux: 回车、换行。 \n


2.指定位置写入

1)Seek():  获取文件读写位置。
       func (f *File) Seek(offset int64, whence int) (ret int64, err error) 
            offset: 矢量。 正数,向文件末尾偏移。负数,向文件开头偏移
            whence: 偏移的起始位置。
                io.SeekStart : 文件起始位置。
                io.SeekCurrent : 文件当前位置。    
                io.SeekEnd: 文件末尾位置。
            返回值 ret: 从文件起始位置到,读写位置的偏移量。                        

2)WriteAt(): 在指定位置写入数据。, 通常搭配 Seek()用
        func (f *File) WriteAt(b []byte, off int64) (n int, err error)
            b: 待写入的数据内容
            off:写入的位置。(通常是 Seek函数的 返回值)    

例子:

package main

import (
    "os"
    "fmt"
    "io"
)

func main()  {

    f, err := os.Create("./test.txt")
    if err != nil {
        fmt.Println("Create err:", err)
        return
    }
    defer f.Close()

    n, err := f.WriteString("hello world\r\n")
    if err != nil {
        fmt.Println("WriteString err:", err)
        return
    }
    fmt.Println("n = ", n)

    //off, err := f.Seek(5, io.SeekStart)
    off, err := f.Seek(-5, io.SeekEnd)
    if err != nil {
        fmt.Println("Seek err:", err)
        return
    }
    fmt.Println("off:", off)

    n, err = f.WriteAt([]byte("1111"), off)
    if err != nil {
        fmt.Println("WriteAt err:", err)
        return
    }

    fmt.Println("write successful")
}
View Code

 

3.按字节写--按字节读 :重要!!!!! ---- 按字节处理文件。既可以处理文本也可以处理二进制文件(.jpg/mp3/avi....)

func (file *File) Read(b []byte) (n int, err Error)

   b: 用来存储读到的数据的 缓冲区。

   返回n:实际读到的 字节数。

 func (file *File) Write(b []byte) (n int, err Error)

   b: 存储数据的缓冲区,其中的数据即将被写入文件。。

   返回n:实际写出的 字节数。

 
 1 func main01()  {
 2     f, err := os.OpenFile("test.txt", os.O_RDWR, 0600)
 3     if err != nil {
 4         fmt.Println("Open err:", err)
 5         return
 6     }
 7     defer f.Close()
 8 
 9     buf := make([]byte, 4096)    // 4k
10 
11     n, err := f.Read(buf)
12     if err != nil {
13         fmt.Println("Read err:", err)
14         return
15     }
16     fmt.Printf("read data:%s", buf[:n])
17 }
18 
19 func main02()  {
20     f, err := os.OpenFile("test.txt", os.O_RDWR, 0600)
21     if err != nil {
22         fmt.Println("Open err:", err)
23         return
24     }
25     defer f.Close()
26 
27     n, err := f.Write([]byte("AAA"))
28     if err != nil {
29         fmt.Println("Write err:", err)
30         return
31     }
32     fmt.Println("n = ", n)
33 }
按照字节读写

 

读文件:bufio

按行读。----- 处理文本文件。
        1) 获取一个 reader(自带缓冲区)
            func NewReader(rd io.Reader) *Reader 
                rd: 成功打开的文件指针。 f
                返回值:Reader (阅读器,自带缓冲区)
        2)从 reader 的缓冲区中获取 指定数据 ReadBytes( \'\n\' )
            func (b *Reader) ReadBytes(delim byte) ([]byte, error)
                delim :读取数据的拆分依据。
                返回值:成功获取到的数据内容。
        通常,会使用 for 来循环调用  ReadBytes, 一直读到 err == io.EOF 的时候,结束信息。代表文件读取完毕。
 1 package main
 2 
 3 import (
 4     "os"
 5     "fmt"
 6     "bufio"
 7     "io"
 8 )
 9 
10 func main()  {
11     f, err := os.Open("test.txt")
12     if err != nil {
13         fmt.Println("Open err:", err)
14         return
15     }
16     defer f.Close()
17 
18     // 获取阅读器 reader, 自带缓冲区(用户缓冲)。
19     reader := bufio.NewReader(f)
20 
21     for {            // 循环读取文件, 当 err == io.EOF 结束循环
22         // 使用 带分割符的 函数,读取指定数据 ‘\n’获取一行
23         buf, err := reader.ReadBytes(\'\n\')
24         // 成功读取到的一行数据 保存在 buf中
25         fmt.Printf("buf:%s", buf)
26         if err != nil && err == io.EOF {
27             break
28         }
29     }
30     fmt.Println("文件读取完毕")
31 }
按行读文件

读目录:

1) 打开目录  OpenFile
        func OpenFile(name string, flag int, perm FileMode) (*File, error) 
            flag: 只能指定 O_RDONLY
            perm : os.ModeDir        ---> 操作目录文件
            返回: 操作目录文件的 指针    
2) 读取目录项  Readdir
        func (f *File) Readdir(n int) ([]FileInfo, error)
            n:读取目录项的个数。 -1 表全部
            返回值:每一个目录项 描述信息的(FileInfo) 切片
[]FileInfo 切片
       type FileInfo interface {
        Name() string       // base name of the file
        Size() int64        // length in bytes for regular files; system-dependent for others
        。。。
        IsDir() bool        // abbreviation for Mode().IsDir()
        。。。
      }            
 1 package main
 2 
 3 import (
 4     "os"
 5     "fmt"
 6 )
 7 
 8 func main()  {
 9     var dir string
10     fmt.Print("请输入一个待判定的目录:")
11     fmt.Scan(&dir)
12 
13     // 打开目录
14     f, err := os.OpenFile(dir, os.O_RDONLY, os.ModeDir)
15     if err != nil {
16         fmt.Println("OpenFile err:", err)
17         return
18     }
19     defer f.Close()
20 
21     // 读取目录项 -- 将一个目录下的所有内容, 存入[]FileInfo
22     fileInfo, err := f.Readdir(-1)
23     if err != nil {
24         fmt.Println("Readdir err:", err)
25         return
26     }
27 
28     // 依次取出目录项
29     for _, dirInfo := range fileInfo {
30         if dirInfo.IsDir() {
31             fmt.Printf("%s 是一个 目录\n", dirInfo.Name())
32         } else {
33             fmt.Printf("%s is not 目录\n", dirInfo.Name())
34         }
35     }
36 
37 }
读取目录

 

练习例子

大文件拷贝实现:
1
. 只读打开文件 os.Open --> fr defer close() 2. 创建新文件 os.Create --> fw defer close() 3. for 循环安字节读取 fr 中的所有数据, 存入 buf 4. 读多少,写多少,将buf 中数据写入 fw 5. 判断 err == io.EOF 来确认读到文件末尾。
package main

import (
    "os"
    "fmt"
    "io"
)

func main()  {
    // 创建 待读取的文件,和 待写入的文件
    f_r, err := os.Open("C:/itcast/01-结构体的定义和初始化.avi")
    if err != nil {
        fmt.Println("open err:", err)
        return
    }
    defer f_r.Close()

    f_w, err := os.Create("./test.avi")
    if err != nil {
        fmt.Println("Create err:", err)
        return
    }
    defer f_w.Close()

    buf := make([]byte, 4096)    //创建缓冲区,存储读到的数据

    // 循环从 f_r 对应文件中读取数据,
    for {
        n, err := f_r.Read(buf)
        if err == io.EOF {
            fmt.Println("读取文件完成")
            break
        }
        if err != nil {
            fmt.Println("Read err:", err)
            return
        }
        // 原封不动写到 f_w 文件中, 读多少,写多少
        n, err = f_w.Write(buf[:n])
        if err != nil {
            fmt.Println("Write err:", err)
            return
        }
    }

    os.OpenFile()
}
View Code

练习1  初级练习

func main() {
    //从用户给出的目录中,找出所有的 .jpg 文件
     var path string
     fmt.Scan(&path)
     f,err:=os.OpenFile(path,os.O_RDONLY,os.ModeDir)
     if err!=nil{
         fmt.Println(err)
         return
     }
     fileinfo,err:=f.Readdir(-1)
     if err!=nil{
        fmt.Println("err",err)
        return
    }
     for _,i:=range fileinfo{
        if strings.HasSuffix(i.Name(),"jpg"){
            fmt.Println(i.Name())
        }
    }
从用户给出的目录中,找出所有的 .jpg 文件

练习2 中级练习

package main

import (
    "fmt"
    "os"
    "strings"
    "io"
)

func copyMp3ToDir(fileName, path string)  {
    pathName := path + "/" + fileName
    fr, err := os.Open(pathName)                // 打开 源文件
    if err != nil {
        fmt.Println("Open err:", err)
        return
    }
    defer fr.Close()

    fw, err :=os.Create("./" + fileName)        // 打开拷贝的文件
    if err != nil {
        fmt.Println("Create err:", err)
        return
    }
    defer fw.Close()

    // 创建一个用于read 存储数据的 buf
    buf := make([]byte, 4096)

    // 循环从 fr 中读取数据, 原封不动 写到 fw中
    for {
        n, err := fr.Read(buf)
        if n == 0 {
            fmt.Println("文件拷贝完毕")
            break
        }
        if err != nil && err != io.EOF {
            fmt.Println("err:", err)
        }
        fw.Write(buf[:n])      // 读多少,写多少
    }

}

func main()  {
    // 请用户指定 目录
    var path string
    fmt.Print("请输入目录位置:")
    fmt.Scan(&path)

    // 打开指定目录位置
    dir_fp, err := os.OpenFile(path, os.O_RDONLY, os.ModeDir)
    if err != nil {
        fmt.Println("Openfile err:", err)
        return
    }
    defer dir_fp.Close()

    // 读取目录项
    dirsInfo, err := dir_fp.Readdir(-1)
    if err != nil {
        fmt.Println("Readdir err:", err)
        return
    }
    // 从目录项[] 中提取每一个目录项
    for _, dir := range dirsInfo {
        fileName := dir.Name()
        // 根据后缀名,筛选文件
        if strings.HasSuffix(fileName, ".mp3") {

            // 将该文件 copy 至指定目录
            copyMp3ToDir(fileName, path)
            //fmt.Println("mp3文件有:", fileName)
        }
    }
}
从用户给出的目录中,拷贝 .mp3文件到指定目录中。
    //2.从用户给出的目录中,拷贝 .mp3文件到指定目录中。
    args:=os.Args
    f1,err:=os.OpenFile(args[1],os.O_RDONLY,os.ModeDir)
    if err!=nil{
        fmt.Println(err)
        return
    }
    fmt.Println(args[1],args[2])
    fileinfo,err:=f1.Readdir(-1)
    if err!=nil {
        fmt.Println(err)
    }
    for _,name:=range fileinfo{
        //fmt.Println(name)
        if strings.HasSuffix(name.Name(),".mp3"){
            fmt.Println(name.Name())
            copyfile(args[1]+"/"+name.Name(),args[2]+"/"+name.Name())
        }
    }
    defer f1.Close()
}
func copyfile(dst,src string){
    buf:=make([]byte,4096)
    f1, err := os.OpenFile(dst, os.O_RDONLY, 0666)
    if err != nil {
        fmt.Println(err)
        return
    }
    fw, err := os.Create(src)
    if err != nil {
        fmt.Println(err)
        return
    }
    for {
        n, err := f1.Read(buf)
        if err != nil || err ==io.EOF{
            fmt.Println(err)
            break
        }
        fw.Write(buf[:n])
    }
        defer fw.Close()
自己写的

练习3  高级练习

 1 package main
 2 
 3 import (
 4     "os"
 5     "fmt"
 6     "strings"
 7     "bufio"
 8     "io"
 9 )
10 
11 func countLove(fileName, path string) int {
12     // 打开文件,txt
13     f, err := os.Open(path + "/" + fileName)
14     if err != nil {
15         fmt.Println("Open err:", err)
16         return -1
17     }
 
                       
                    
                    

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Go语言开发Windows应用 - 轩脉刃发布时间:2022-07-10
下一篇:
Go语言基础之文件操作发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap