目录
1.获取文件信息
1.fileInfo,err = os.Stat("文件路径")
2.fileInfo的方法:
Name:文件名称
Size:文件大小:字节
Mode:文件权限:
ModTime:最后修改时间
IsDir:是否是文件夹
Sys:获取更加详细的信息,反射的时候讲
3.文件权限:
文件类型
-代表文件
d代表目录
权限
r(4) 读
w(2) 写
x(1) 执行
func main() {
fileInfo, err := os.Stat("./day013/a.txt") // ./代表src下各个项目的路径
if err == nil {
fmt.Println("文件名:", fileInfo.Name())
fmt.Println("文件大小:", fileInfo.Size())
fmt.Println("文件权限:", fileInfo.Mode())
fmt.Println("最后修改时间:", fileInfo.ModTime())
fmt.Println("是否是文件夹:", fileInfo.IsDir())
fmt.Println("sys:", fileInfo.Sys())
}
}
2.目录与文件
1.目录:
创建:
os.Mkdir("文件路径","文件权限"):创建单级目录,如果文件夹存在就报错,不存在就创建
os.MkdirAll("文件路径","文件权限"):创建多级目录
删除:
os.Remove("文件路径"):删除空目录
os.RemoveAll("文件路径"):删除目录及目录下所有文件和文件夹
2.文件
创建:
os.Crete("文件路径"):创建文件
删除:
os.Remove("文件路径"):删除文件
func main() {
//1.创建单级目录
err := os.Mkdir("./day013/a", os.ModePerm)
if err == nil {
fmt.Println("目录a创建成功")
}
//2.创建多级目录
err2 := os.MkdirAll("./day013/b/c/d", os.ModePerm)
if err2 == nil {
fmt.Println("目录b,c,d创建成功")
}
//3.删除空目录
err3 := os.Remove("./day013/a")
if err3 == nil {
fmt.Println("目录a删除成功")
}
//4.删除目录及目录下所有文件和文件夹
err4 := os.RemoveAll("./day013/b")
if err4 == nil {
fmt.Println("目录b删除成功")
}
//5.创建文件
file, err5 := os.Create("./day013/a.go")
if err5 == nil {
fmt.Println(file.Name(), "创建成功")
}
//6.删除文件
err6 := os.Remove("./day013/a.go")
if err6 == nil {
fmt.Println("a.go 文件删除成功")
}
}
3.读取文件中的数据
1.打开文件
方式一:
file,err := os.Open("文件路径") 只能用于读取文件
方式二:
file,err := os.OpenFile("文件路径",文件打开方式,文件权限)
注:文件打开方式
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 可读可写
O_APPEND 追加写
O_CREATE 如果文件不存在,则创建一个新的文件
O_EXCL 文件必须不存在,然后会创建一个新的文件
O_SYNC 打开同步I/0
O_TRUNC 文件打开时可以截断
2.读取文件中的数据:读取完之后再读取报错EOF
本次读取的数据长度,err := file.Read(切片)
func main() {
//1.打开文件
file1, err := os.Open("./day013/a.txt")
defer file1.Close()
if err == nil {
//2.读取文件中的数据
buf1 := make([]byte, 1024, 1024)
len, err2 := file1.Read(buf1)
if err2 == nil {
//本次读取的文件长度为:8,内容为:zhangsan
fmt.Printf("本次读取的文件长度为:%d,内容为:%v\n", len, string(buf1[:len]))
}
}
//3.打开文件
file2, err3 := os.OpenFile("./day013/a.txt", os.O_RDONLY, os.ModePerm)
defer file2.Close()
if err3 == nil {
//4.读取文件中的数据
buf2 := make([]byte, 1024, 1024)
len, err4 := file2.Read(buf2)
if err4 == nil {
//本次读取的文件长度为:8,内容为:zhangsan
fmt.Printf("本次读取的文件长度为:%d,内容为:%v\n", len, string(buf2[:len]))
}
}
}
4.向文件中写入数据
1.打开文件
file,err := os.OpenFile("文件路径",文件打开方式,文件权限)
2.写入数据到文件
方式一:将切片中的数据写入到文件
本次写入的数据长度, err := file.Write(切片)
方式二:将字符串写入到文件中
本次写入的数据长度, err := file.WriteString(字符串)
func main() {
//1.打开文件
file, err := os.OpenFile("./day013/a.txt", os.O_RDWR|os.O_APPEND, os.ModePerm)
defer file.Close()
if err == nil {
//2.向文件中写入数据
//方式一:将切片中的数据写入到文件
data := make([]byte, 0, 1024)
data = append(data, 65, 66, 67, 68, 69)
len1, err2 := file.Write(data)
if err2 == nil {
fmt.Printf("本次写入的数据长度为:%d\n", len1)
}
//方式二:将字符串写入到文件中
len2, err3 := file.WriteString("进击的小张")
if err3 == nil {
fmt.Printf("本次写入的数据长度为:%d\n", len2)
}
}
}
5.拷贝文件的三种方法
方式一:自定义文件拷贝函数
1.打开源文件
2.打开目标文件
3.读取源文件中的数据
4.将读取的数据写入到目标文件
方式二:使用io包的copy方法实现文件拷贝:默认缓冲区大小:32*1024,推荐使用此方法
1.打开源文件
2.打开目标文件
3.将源文件中的数据拷贝到目标文件
拷贝的文件长度, err := io.Copy(目标文件, 源文件)
方式三:使用os包的ReadFile、WriteFile方法实现文件拷贝:不推荐使用此方法,一次读取到缓冲区中,文件过大会导致内存溢出
1.读取文件
存储读取的数据的切片, err := os.ReadFile(源文件路径)
2.写入文件
err := os.WriteFile(目标文件路径, 存储读取的数据的切片, 权限)
func main() {
//copy1("./day013/meimv1.jpeg", "./day013/sucai.jpeg", 1024)
//copy2("./day013/meimv2.jpeg", "./day013/sucai.jpeg")
copy3("./day013/meimv3.jpeg", "./day013/sucai.jpeg")
}
// 方式一:存在断电后不能文件续传问题,下面解决
func copy1(targetPath, sourcePath string, bufSize int) {
//打开源文件
sourceFile, err1 := os.OpenFile(sourcePath, os.O_RDONLY, os.ModePerm)
defer sourceFile.Close()
if err1 != nil {
fmt.Println("源文件打开失败")
return
}
//打开目标文件
targetFile, err2 := os.OpenFile(targetPath, os.O_CREATE|os.O_WRONLY, os.ModePerm)
defer targetFile.Close()
if err2 != nil {
fmt.Println("目标文件打开失败")
return
}
//统计文件大小
len := 0
for {
//读取文件
buf := make([]byte, bufSize, bufSize)
len1, err3 := sourceFile.Read(buf)
if err3 == io.EOF || len1 == 0 {
fmt.Printf("文件拷贝完成,大小:%d字节\n", len)
return
}
//写入文件
len2, err4 := targetFile.Write(buf[:len1])
if err4 != nil {
fmt.Println("文件写入失败")
}
len += len2
}
}
//方式二:推荐
func copy2(targetPath, sourcePath string) {
//打开源文件
sourceFile, err1 := os.OpenFile(sourcePath, os.O_RDONLY, os.ModePerm)
defer sourceFile.Close()
if err1 != nil {
fmt.Println("源文件打开失败")
return
}
//打开目标文件
targetFile, err2 := os.OpenFile(targetPath, os.O_CREATE|os.O_WRONLY, os.ModePerm)
defer targetFile.Close()
if err2 != nil {
fmt.Println("目标文件打开失败")
return
}
//拷贝
len, err3 := io.Copy(targetFile, sourceFile)
if err3 != nil {
fmt.Println("文件拷贝失败")
return
}
fmt.Printf("文件拷贝完成,大小:%d字节\n", len)
}
//方式三:不推荐
func copy3(targetPath, sourcePath string) {
//读取源文件中的数据
buf, err1 := os.ReadFile(sourcePath)
if err1 != nil {
fmt.Println("源文件数据读取失败")
return
}
//将数据写入到目标文件
err2 := os.WriteFile(targetPath, buf, os.ModePerm)
if err2 != nil {
fmt.Println("文件写入失败")
return
}
fmt.Println("文件拷贝完成")
}
6.设置光标所在位置
file.Seek(偏移量, 光标所在位置)
1.offset偏移量:
相对于光标向右偏移几个位置;
2.whence:如何设置
io.seekStart 相对于文件开头
io.seekCurrent 相对于光标所在位置
io.seekEnd 相对于文件末尾
func main() {
//打开文件
file, err1 := os.OpenFile("./day013/a.txt", os.O_RDWR|os.O_APPEND, os.ModePerm)
defer file.Close()
if err1 != nil {
fmt.Println("文件打开失败")
return
}
//从文件开头第6个读取数据
file.Seek(5, io.SeekStart)
buf := make([]byte, 3, 1024)
len1, err2 := file.Read(buf)
if err2 != nil {
fmt.Println("文件读取失败")
return
}
fmt.Printf("本次读取的的数据为:%v\n", string(buf[:len1]))
//从当前光标所在位置第2个读取数据
file.Seek(2, io.SeekCurrent)
len2, err3 := file.Read(buf)
if err3 != nil {
fmt.Println("文件读取失败")
return
}
fmt.Printf("本次读取的的数据为:%v\n", string(buf[:len2]))
//从文件末尾追加数据
file.Seek(0, io.SeekEnd)
len3, err4 := file.WriteString("我是新增的数据")
if err4 != nil {
fmt.Println("追加数据失败")
return
}
fmt.Printf("本次追加的数据长度为:%d\n", len3)
}
7.文件断点续传案例
文件断点续传:创建一个临时文件存储文件复制的字节数
思路:
1.打开文件(源文件、目标文件、临时文件)
2.读取临时文件中存储的已复制的文件字节数
3.设置源文件和目标文件为临时文件记录的字节数
4.拷贝文件
5.临时文件更新拷贝进度
func main() {
copy("./day013/meimv4.jpeg", "./day013/sucai.jpeg")
}
func copy(targetPath, sourcePath string) {
//打开文件(源文件、目标文件、临时文件)
sourceFile, err1 := os.OpenFile(sourcePath, os.O_RDONLY, os.ModePerm)
defer sourceFile.Close()
if err1 != nil {
fmt.Println("源文件打开失败")
return
}
targetFile, err2 := os.OpenFile(targetPath, os.O_RDWR|os.O_APPEND|os.O_CREATE, os.ModePerm)
defer targetFile.Close()
if err2 != nil {
fmt.Println("目标文件打开失败")
return
}
tempPath := "./day013/temp.txt"
tempFile, err3 := os.OpenFile(tempPath, os.O_CREATE|os.O_RDWR, os.ModePerm)
defer tempFile.Close()
if err3 != nil {
fmt.Println("临时文件打开失败")
return
}
//读取临时文件中传输的字节数
tempBuf := make([]byte, 1024, 1024)
tempLen, _ := tempFile.Read(tempBuf)
count, err4 := strconv.Atoi(string(tempBuf[:tempLen]))
if err4 != nil {
count = 0
}
fmt.Printf("上次文件传输了:%d字节\n", count)
//文件拷贝
dateBuf := make([]byte, 1024, 1024)
sourceFile.Seek(int64(count), io.SeekStart)
targetFile.Seek(int64(count), io.SeekStart)
for {
//读取源文件中的数据
len1, err5 := sourceFile.Read(dateBuf)
if err5 == io.EOF || len1 == 0 {
os.Remove(tempPath)
fmt.Println("文件拷贝完成")
return
}
//写入数据到目标文件
len2, err6 := targetFile.Write(dateBuf)
if err6 != nil {
fmt.Println("文件写入失败")
return
}
//临时文件更新拷贝进度
tempFile.Seek(0, io.SeekStart)
count += len2
tempFile.WriteString(strconv.Itoa(count))
//模拟断电拷贝报错
/*if count > 10000 {
panic("模拟断电情况")
}*/
}
}
8.bufio包
bufio
1.读取键盘输入的数据
2.读取文件中的数据
3.向文件中写入数据
func main() {
//1.读取键盘输入的数据
fmt.Println("请输入一段内容,按回车结束")
reader1 := bufio.NewReader(os.Stdin)
readString, err1 := reader1.ReadString('\n')
if err1 != nil {
fmt.Println("键盘输入数据读取失败")
return
}
fmt.Println("键盘输入的内容为:", readString)
file, err2 := os.OpenFile("./day013/a.txt", os.O_RDWR, os.ModePerm)
defer file.Close()
if err2 != nil {
fmt.Println("文件打开失败")
return
}
//2.读取文件中的数据
reader2 := bufio.NewReader(file)
buf := make([]byte, 1024, 1024)
len, err3 := reader2.Read(buf)
if err3 != nil {
fmt.Println("文件读取失败")
return
}
fmt.Println("读取到到数据为:", string(buf[:len]))
//3.向文件中写入数据
writer := bufio.NewWriter(file)
len2, err4 := writer.WriteString("我是新内容")
if err4 != nil {
fmt.Println("文件写入失败")
return
}
writer.Flush()
fmt.Println("写入的数据长度为:", len2)
}
9.遍历文件夹下的所有目录和文件
1.获取目录下的所有文件和文件夹:dirList, err := os.ReadDir(filePath)
func main() {
foreachDir(".")
}
// 遍历目录
func foreachDir(filePath string) {
dirList, err1 := os.ReadDir(filePath)
if err1 != nil {
fmt.Println("目录读取失败")
return
}
for _, file := range dirList {
filePath2 := filePath + "/" + file.Name()
fmt.Println(filePath2)
if file.IsDir() {
foreachDir(filePath2)
}
}
}