Golang-记使用go语言操作文件
自2019下半年开始,学徒在有意无意的,时断时续的学习golang,需要找些机会去实践go编程,找不机会就硬找。
学徒使用UWP版的bilibili客户端下载了一些bilibili平台的教学视频(众所周知,bilibili是一个专业的学习平台),然而视频下载完后,发现下载的视频文件并非存储在一个文件目录中,非常不方便将整个系列视频添加到播放列表或者分享交流。所以学徒打算将下载的文件整理出来,整理的过程正是使用Golang实现。
实现需求
- 未整理前,具体看图
- 整理后
实现步骤
从上图看可以列一下编程步骤。
- 读取ini文件拿到系列视频名称
- 以系列视频名称新创建文件目录
- 读取json文件获取视频文件名称
- 拷贝视频文件并重命名至新创建的文件目录中
编码实现
需要安装的库
# 安装mahonia,编码转换,解决中文乱码问题
$ go get github.com/axgle/mahonia
# 安装go-ini,帮助解析ini文件,获取键值
$ go get gopkg.in/ini.v1
# 或
$ go get github.com/go-ini/ini
编码分了三个文件
- vars.go,存储文件整理的一些参数
package main
var bilibiliDownloadPath = "E:\\resource\\downloads\\bilibili"
var destPath = "E:\\videos"
- bva.go,bilibili视频文件整理用到的方法
package main
import (
"encoding/json"
"fmt"
"github.com/axgle/mahonia" //编码转换
"gopkg.in/ini.v1"
"io"
"io/ioutil"
"os"
)
var enc = mahonia.NewDecoder("gbk")
// 根据文件名,段名,键名获取ini的值
func getIniValue(filename, expectSection, expectKey string) string {
// enc := mahonia.NewDecoder("gbk")
iniFile, err := ini.Load(filename)
if err != nil {
return ""
}
val := iniFile.Section(expectSection).Key(expectKey).String()
return enc.ConvertString(val)
}
type VideoInfo struct {
PartName string
}
// 根据文件名,段名,键名获取ini的值
func getJsonValue(filename string) string {
// enc := mahonia.NewDecoder("gbk")
jsonFile, err := os.Open(filename)
if err != nil {
return ""
}
jsonBytes, err := ioutil.ReadAll(jsonFile)
var videoInfo VideoInfo
json.Unmarshal(jsonBytes, &videoInfo)
return videoInfo.PartName
}
// 文件Copy
func CopyFile(srcName, destName string) error {
src, err := os.Open(srcName)
if err != nil {
return fmt.Errorf("File Open Failed.")
}
defer src.Close()
dest, err := os.Create(destName)
if err != nil {
return fmt.Errorf("File Create Failed.")
}
defer dest.Close()
_, err = io.Copy(dest, src)
if err != nil {
return fmt.Errorf("File Copy Failed.")
}
return nil
}
- main.go,程序入口
package main
import (
"fmt"
"io/ioutil"
"os"
)
func main() {
// 获取所有系列视频目录
fis, err := ioutil.ReadDir(bilibiliDownloadPath)
if err != nil {
fmt.Println("ReadDir Failed! Path:" + bilibiliDownloadPath)
return
}
// 处理每个系列目录
for _, fi := range fis {
if fi.IsDir() {
HandlerSingleSeries(fi)
}
}
}
func HandlerSingleSeries(fi os.FileInfo) {
fiPath := bilibiliDownloadPath + "\\" + fi.Name() // 系列目录
// 读取ini文件拿到系列视频名称
iniFilePath := fiPath + "\\desktop.ini"
seriesName := getIniValue(iniFilePath, ".ShellClassInfo", "InfoTip")
if seriesName != "" {
// 以系列视频名称新创建文件目录
seriesPath := destPath + "\\" + seriesName
err := os.Mkdir(seriesPath, os.ModePerm)
if err != nil {
fmt.Print("Mkdir Failed! Path:" + seriesPath)
}
vfis, err := ioutil.ReadDir(fiPath)
if err != nil {
fmt.Println("ReadDir Failed! Path:" + fiPath)
return
}
for _, vfi := range vfis {
if vfi.IsDir() {
// 读取json文件获取视频文件名称
jsonFileName := fiPath + "\\" + vfi.Name() + "\\" + fi.Name() + ".info"
pName := getJsonValue(jsonFileName) // 分P名称,视频文件名
if pName != "" {
// 拷贝视频文件并重命名至新创建的文件目录中
fiSrcPath := fiPath + "\\" + vfi.Name() + "\\" + fi.Name() + "_" + vfi.Name() + "_0.flv"
fiDestPath := seriesPath + "\\" + pName + ".flv"
CopyFile(fiSrcPath, fiDestPath)
}
}
}
}
}
程序上传至:github
结束语
Golang的编程体验很不错,入门算是非常简单的。变量的声明比较新颖,可以通过下载github上的库直接引用。Golang有着天然支持高并发编程的有点,又作为区块链的主要编程语言,还是很有学习意义的。