Skip to main content

go-file

Golang 操作文件的一些方法

检查一个文件是否存在

例1
package main
import(
   "fmt"
   "os"
)
func main() {
   if _, err := os.Stat("sample.txt"); err == nil {
      fmt.Printf("File exists\n");
   } else {
      fmt.Printf("File does not exist\n");
   }
}
//在上面的代码中,我们试图在 os.Stat() 函数的帮助下找到一个名为 sample.txt 的文件的存在,然后如果我们没有遇到错误,我们将得到打印到终端的第一个 Printf() 语句。
//输出 File exists

上面的方法很好用,但是有一个问题。可能是这样,从 Stat() 函数返回的b err 可能是由于权限错误或磁盘故障,因此建议在使用 os.Stat() 函数的同时也使用 isNotExists(err) 函数。

例2
package main
import(
"fmt"
"os"
)
func main() {
if fileExists("sample.txt") {
fmt.Println("sample file exists")
} else {
fmt.Println("sample file does not exist")
}
}
func fileExists(filename string) bool {
info, err := os.Stat(filename)
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}
//输出 File exists

一、使用os包遍历目录

在Golang中,使用os包可以轻松地遍历目录,并执行一些操作。通过使用os包中的Walk方法,可以深度优先地遍历目录结构。下面是一个简单的示例
import (
"fmt"
"os"
"path/filepath"
)

func main() {
root := "/path/to/root/directory"
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
fmt.Println(path)
return nil
})
if err != nil {
panic(err)
}
}

首先,我们指定根目录,然后使用filepath.Walk方法遍历该目录。在回调函数中,我们可以访问每个文件的相关信息,例如路径,大小和修改时间。

二、遍历目录并获取文件信息

在许多情况下,我们需要获取目录中的文件,并在进一步处理它们之前获得有关它们的一些信息。通过使用os包的Readdir方法,在Golang中获取文件信息非常简单
func main() {
root := "/path/to/root/directory"
files, err := ioutil.ReadDir(root)
if err != nil {
panic(err)
}
for _, f := range files {
fmt.Println(f.Name(), f.IsDir(), f.Size())
}
}

我们首先使用ReadDir方法读取根目录中的文件。这将返回一个FileInfoslice,我们可以通过遍历这个slice访问每个文件的信息,例如文件名,大小和是否为目录。这对于查找目录中的文件或过滤出指定类型的文件非常有用。

三、遍历目录并筛选出文件

有时我们需要遍历目录中的所有文件,并根据我们的需求获得特定类型的文件。我们可以使用filepath包中的Glob方法来做到这一点。
func main() {
root := "/path/to/root/directory"
files, err := filepath.Glob(filepath.Join(root, "*.txt"))
if err != nil {
panic(err)
}
for _, file := range files {
fmt.Println(file)
}
}

在这个示例中,Glob方法将匹配所有扩展名为.txt的文件,并返回它们的完整路径。通过这种方式,可以将搜索结果限制为我们感兴趣的文件类型。

四、同步遍历目录

在某些情况下,我们需要在遍历目录时同步进行某些操作,例如复制或移动文件。通过使用Golang的channel和goroutine概念,我们可以在同步方式下遍历目录并执行操作。
func main() {
var wg sync.WaitGroup
root := "/path/to/root/directory"
files := make(chan string)
wg.Add(1)
go func() {
defer wg.Done()
filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
files <- path
}
return nil
})
close(files)
}()

for file := range files {
fmt.Println(file)
}

wg.Wait()
}

在这个示例中,我们使用了一个文件通道来存储遍历得到的每一个文件路径。在goroutine内,我们使用Walk遍历根目录,如果文件不是目录,我们将其发送到通道中。在主函数中,我们遍历通道并输出每个文件的路径。

五、使用第三方库

除了标准库之外,还有许多第三方库可用于在Golang中处理文件和目录。例如,afero 是一个由文件系统抽象API组成的包,可以使用各种存储介质进行读写。
import (
"fmt"
"github.com/spf13/afero"
)

func main() {
root := "/path/to/root/directory"
appFs := afero.NewBasePathFs(afero.NewOsFs(), root)
files, err := afero.ReadDir(appFs, ".")
if err != nil {
panic(err)
}
for _, f := range files {
fmt.Println(f.Name(), f.IsDir(), f.Size())
}
}

afero提供了在所有支持的文件系统中轻松进行处理的接口,而无需担心单个文件系统的限制。它还提供了许多其他功能,例如递归删除目录和注册新的文件系统。

六,读取Excel表格

package main

import (
"fmt"
"github.com/extrame/go-xlsx"
"log"
)

func main() {
xlFile, err := xlsx.OpenFile("example.xlsx")
if err != nil {
log.Fatal(err)
}

for _, sheet := range xlFile.Sheets {
for _, row := range sheet.Rows {
for _, cell := range row.Cells {
fmt.Printf("%s ", cell.String())
}
fmt.Println()
}
}
}

七, 计算两个时间差

package main

import (
"fmt"
"time"
)

func main() {
// 定义两个时间点
time1 := time.Now() // 当前时间
time.Sleep(2 * time.Second) // 等待2秒
time2 := time.Now() // 2秒后的时间

// 计算时间差
elapsed := time2.Sub(time1)

// 输出时间差
fmt.Printf("Time elapsed: %s\n", elapsed)
}

八,判断目录是否为空

package main

import (
"fmt"
"os"
)

func isDirEmpty(name string) (bool, error) {
infos, err := os.ReadDir(name)
if err != nil {
return false, err
}
return len(infos) == 0, nil
}

func main() {
dir := "/path/to/directory"
empty, err := isDirEmpty(dir)
if err != nil {
fmt.Printf("Error checking directory: %s\n", err)
return
}
if empty {
fmt.Printf("Directory %s is empty.\n", dir)
} else {
fmt.Printf("Directory %s is not empty.\n", dir)
}
}

九. kill windows 进程

package main

import (
"os/exec"
"strconv"
"strings"
"fmt"
)

func killWindowsProcess(processName string) error {
// 查找进程ID
cmd := exec.Command("tasklist", "/FI", "IMAGENAME eq "+processName, "/FO", "CSV")
output, err := cmd.CombinedOutput()
if err != nil {
return err
}

// 解析CSV输出
lines := strings.Split(string(output), "\r\n")
for _, line := range lines {
if len(line) == 0 {
continue
}
parts := strings.Split(line, ",")
if len(parts) < 2 {
continue
}
pid, err := strconv.Atoi(strings.Trim(parts[1], `" `))
if err != nil {
continue
}
// 杀掉进程
cmd := exec.Command("taskkill", "/F", "/PID", strconv.Itoa(pid))
err = cmd.Run()
if err != nil {
return err
}
}
return nil
}

func main() {
err := killWindowsProcess("notepad.exe")
if err != nil {
fmt.Println("Error killing process:", err)
} else {
fmt.Println("Process killed successfully")
}
}

十, excel 操作 写入

package main

import (
"fmt"
"github.com/tealeg/xlsx"
"os"
)

func main() {
// 创建一个新的工作簿
file := xlsx.NewFile()
sheet, err := file.AddSheet("Sheet1")
if err != nil {
fmt.Printf(err.Error())
return
}

// 写入数据
_, err = sheet.Cell(0, 0).SetString("Hello")
if err != nil {
fmt.Printf(err.Error())
return
}
_, err = sheet.Cell(0, 1).SetString("World")
if err != nil {
fmt.Printf(err.Error())
return
}

// 保存文件
err = file.Save("example.xlsx")
if err != nil {
fmt.Printf(err.Error())
return
}

fmt.Println("Excel file created!")
}

十, excel 操作 写入

package main

import (
"fmt"
"github.com/tealeg/xlsx"
)

func main() {
// 打开文件
xlFile, err := xlsx.OpenFile("example.xlsx")
if err != nil {
fmt.Println("Error opening file, exiting")
return
}

// 读取第一个工作表
sheet := xlFile.Sheets[0]

// 遍历行
for _, row := range sheet.Rows {
// 遍历列
for _, cell := range row.Cells {
fmt.Printf("%s ", cell.String())
}
fmt.Println()
}

// --------------other
xlFile, err := xlsx.OpenFile(h.Ename)
if err != nil {
log.Println(err)
return
}
h.Ns = make(map[string]string)
for _, sheet := range xlFile.Sheets {
//log.Println("sheet", len(sheet.Rows))
for k, row := range sheet.Rows {
//log.Println("row", len(row.Cells), k)
if len(row.Cells) > 0 {
h.Ns[row.Cells[0].String()] = row.Cells[0].String()
}
}
}
log.Println("h.Ns", len(h.Ns))
}

十一, excel 操作 写入和读取

package main

import (
"fmt"
"github.com/360EntSecGroup-Skylar/excelize"
)

func main() {
// 创建一个新的Excel文件并写入数据
file := excelize.NewFile()
// 创建一个新的工作表
index := file.NewSheet("Sheet2")
// 设置单元格的值
file.SetCellValue("Sheet2", "A2", "Hello world")
file.SetCellValue("Sheet2", "B2", 100)
// 保存工作表
file.SetActiveSheet(index)
// 保存文件
if err := file.SaveAs("example.xlsx"); err != nil {
fmt.Println(err)
}

// 读取Excel文件中的数据
excel, err := excelize.OpenFile("example.xlsx")
if err != nil {
fmt.Println(err)
return
}
cell, err := excel.GetCellValue("Sheet2", "A2")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(cell) // 输出: Hello world
}

十二,读取 CSV 文件

function readeCsv () {
// 打开CSV文件
file, err := os.Open("resource/aadd.csv")
if err != nil {
panic(err)
}
defer file.Close()

// 创建一个新的读取器
reader := csv.NewReader(file)

// 读取所有记录
records, err := reader.ReadAll()
if err != nil {
panic(err)
}
}

十三 go XML文件,不知道结构的情况

package main

import (
"encoding/xml"
"fmt"
"io"
"os"
)

func main() {
// 打开XML文件
file, err := os.Open("example.xml")
if err != nil {
panic(err)
}
defer file.Close()

// 读取XML内容
decoder := xml.NewDecoder(file)
var stack []string
decoder.Strict = false // 允许不严格的XML格式

for {
token, err := decoder.Token()
if err == io.EOF {
break
} else if err != nil {
panic(err)
}

switch token := token.(type) {
case xml.StartElement:
stack = append(stack, token.Name.Local)
case xml.EndElement:
stack = stack[:len(stack)-1]
case xml.CharData:
if len(stack) > 0 {
key := stack[len(stack)-1]
fmt.Printf("%s: %s\n", key, string(token))
}
}
}
}

十四 go json文件,不知道结构的情况

sls := []string{"name", "mobile"}
// 打开文件
file, err := os.Open("resource/jjj.json")
if err != nil {
global.GVA_LOG.Error("os.Open()", zap.Error(err))

}
defer file.Close()

// 读取文件内容
data, err := io.ReadAll(file)
if err != nil {
panic(err)
}
//dynamicStruct := make(map[string]interface{})
var dynamicStruct map[string]interface{}
json.Unmarshal(data, &dynamicStruct)
log.Println("dynamicStruct", dynamicStruct)
for _, v := range dynamicStruct {
foods, ok := v.([]interface{})
if !ok {
log.Fatal("无法解析json文件")
} else {
// for _, vv := range foods {
// for _, vvv := range sls {
// vv[vvv]
// }
// }
log.Println("foods", foods)
}
break
}