字符串在开发中使用频率较高,我们经常需要对字符串进行拆分、判断等操作,可以借助Go标准库中的strings包快速达到处理字符串的目录。除Contains、Join、Trim、Replace等我们学过的字符串处理函数之外,以下函数也常常会被用到。
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
新建文件可以通过如下两个方法:
func Create(name string) (file *File, err Error)
根据提供的文件名创建新的文件,返回一个文件对象,默认权限是0666的文件,返回的文件对象是可读写的。
通过如下两个方法来打开文件:
func Open(name string) (file *File, err Error)
Open()是以只读权限打开文件名为name的文件,得到的文件指针file,只能用来对文件进行“读”操作。如果我们有“写”文件的需求,就需要借助Openfile函数来打开了。
func OpenFile(name string, flag int, perm uint32) (file *File, err Error)
OpenFile()可以选择打开name文件的读写权限。这个函数有三个默认参数:
·参1:name,表示打开文件的路径。可使用相对路径 或 绝对路径
参2:flg,表示读写模式,常见的模式有:
O_RDONLY(只读模式), O_WRONLY(只写模式), O_RDWR(可读可写模式), O_APPEND(追加模式)。
参3:perm,表权限取值范围(0-7),表示如下:
0:没有任何权限
1:执行权限(如果是可执行文件,是可以运行的)
2:写权限
3: 写权限与执行权限
4:读权限
5: 读权限与执行权限
6: 读权限与写权限
7: 读权限,写权限,执行权限
关闭文件函数:
func (f *File) Close() error
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信息到文件
func (file *File) Read(b []byte) (n int, err Error)
读取数据到b中
func (file *File) ReadAt(b []byte, off int64) (n int, err Error)
从off开始读取数据到b中
func Remove(name string) Error
调用该函数就可以删除文件名为name的文件
示例代码(大文件拷贝):
package main
import (
"fmt"
"io"
"os"
)
func main() {
args := os.Args //获取命令行参数, 并判断输入是否合法
if args == nil || len(args) != 3 {
fmt.Println("useage : xxx srcFile dstFile")
return
}
srcPath := args[1] //获取参数1
dstPath := args[2] //获取参数2
fmt.Printf("srcPath = %s, dstPath = %s\n", srcPath, dstPath)
if srcPath == dstPath {
fmt.Println("error:源文件名 与 目的文件名雷同")
return
}
srcFile, err1 := os.Open(srcPath) // 打开源文件
if err1 != nil {
fmt.Println(err1)
return
}
dstFile, err2 := os.Create(dstPath) //创建目标文件
if err2 != nil {
fmt.Println(err2)
return
}
buf := make([]byte, 1024) //切片缓冲区
for {
//从源文件读取内容,n为读取文件内容的长度
n, err := srcFile.Read(buf)
if err != nil && err != io.EOF {
fmt.Println(err)
break
}
if n == 0 {
fmt.Println("文件处理完毕")
break
}
//切片截取
tmp := buf[:n]
//把读取的内容写入到目的文件
dstFile.Write(tmp)
}
//关闭文件
srcFile.Close()
dstFile.Close()
}
我们读写的文件一般存放于目录中。因此,有时需要指定到某一个目录下,根据目录存储的状况再进行文件的特定操作。接下来我们看看目录的基本操作方法。
打开目录我们也使用 OpenFile 函数,但要指定不同的参数来通知系统,要打开的是一个目录文件。
func OpenFile(name string, flag int, perm FileMode) (*File, error)
参数1:name,表示要打开的目录名称。使用绝对路径较多
参数2:flg,表示打开文件的读写模式。可选择:
O_RDONLY只读模式、O_WRONLY只写模式、O_RDWR读写模式
参数3:perm,表示打开权限。但对于目录来说略有不同。通常传os.ModeDir。
返回值:由于是操作目录,所以file是指向目录的文件指针。error中保存错误信息。
这与读文件有所不同。目录中存放的是文件名和子目录名。所以使用Readdir函数来完成。
func (f *File) Readdir(n int) ([]FileInfo, error)
参数:n,表读取目录的成员个数。通常传-1,表读取目录所有文件对象。
返回值:FileInfo类型的切片。其内部保存了文件名。error中保存错误信息。
type FileInfo interface {
Name() string // base name of the file
Size() int64 // length in bytes for regular files; system-dependent for others
Mode() FileMode // file mode bits
ModTime() time.Time // modification time
IsDir() bool // abbreviation for Mode().IsDir()
Sys() interface{} // underlying data source (can return nil)
}
得到 FileInfo类型切片后,我们可以range遍历切片元素,使用.Name()获取文件名。使用.Size()获取文件大小,使用.IsDir()判断文件是目录还是非目录文件。
如:我们可以提示用户提供一个目录位置,打开该目录,查看目录下的所有成员,并判别他们是文件还是目录。
示例代码:
func main() {
fmt.Println("请输入要找寻的目录:")
var path string
fmt.Scan(&path) // 获取用户指定的目录名
dir, _ := os.OpenFile(path, os.O_RDONLY, os.ModeDir) // 只读打开该目录
names, _ := dir.Readdir(-1) // 读取当前目录下所有的文件名和目录名,存入names切片
for _, name := range names { // 遍历切片,获取文件/目录名
if !name.IsDir() {
fmt.Println(name.Name(), "是一个文件")
} else {
fmt.Println(name.Name(), "是一个目录")
}
}
}
其实,目录也可以看成“文件”。我们通常读写的文件内容是可见的ASCII码。目录文件的内容就是文件名和目录名,称之为目录项。我们读写目录文件,实质上就是在读写目录项。
目录操作还有其他的一系列API,这里简单罗列几个较为常用的,大家可自行酌情学习。
将当前工作目录修改为dir指定的目录:
func Chdir(dir string) error
返回当前工作目录的绝对路径:
func Getwd() (dir string, err error)
使用指定的权限和名称创建一个目录:
func Mkdir(name string, perm FileMode) error
获取更多文件、目录操作API可查看Go标库文档: https://studygolang.com/pkgdoc