[Golang]文件/文件夾一般操作:判斷、複製、刪除、遍歷

1. 檢查指定路徑是否爲文件夾

func IsDir(name string) bool {
	if info, err := os.Stat(name); err == nil {
		return info.IsDir()
	}
	return false
}

2. 檢查文件是否存在

func FileIsExisted(filename string) bool {
	existed := true
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		existed = false
	}
	return existed
}

3. 創建文件夾(如果文件夾不存在則創建)

func MakeDir(dir string) error {
	if !FileIsExisted(dir) {
		if err := os.MkdirAll(dir, 0777); err != nil { //os.ModePerm
			fmt.Println("MakeDir failed:", err)
			return err
		}
	}
	return nil
}

4. 複製文件

複製文件過程中一定要注意將原始文件的權限也要複製過去,否則可能會導致可執行文件不能執行等問題。

//使用io.Copy
func CopyFile(src, des string) (written int64, err error) {
	srcFile, err := os.Open(src)
	if err != nil {
		return 0, err
	}
	defer srcFile.Close()

	//獲取源文件的權限
	fi, _ := srcFile.Stat()
	perm := fi.Mode()

	//desFile, err := os.Create(des)  //無法複製源文件的所有權限
	desFile, err := os.OpenFile(des, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perm)  //複製源文件的所有權限
	if err != nil {
		return 0, err
	}
	defer desFile.Close()

	return io.Copy(desFile, srcFile)
}


//使用ioutil.WriteFile()和ioutil.ReadFile()
func CopyFile2(src, des string) (written int64, err error) {
	//獲取源文件的權限
	srcFile, err := os.Open(src)
	if err != nil {
		return 0, err
	}
	fi, _ := srcFile.Stat()
	perm := fi.Mode()
	srcFile.Close()

	input, err := ioutil.ReadFile(src)
	if err != nil {
		return 0, err
	}

	err = ioutil.WriteFile(des, input, perm)
	if err != nil {
		return 0, err
	}

	return int64(len(input)), nil
}


//使用os.Read()和os.Write()
func CopyFile3(src, des string, bufSize int) (written int64, err error) {
	if bufSize <= 0 {
		bufSize = 1*1024*1024   //1M
	}
	buf := make([]byte, bufSize)

	srcFile, err := os.Open(src)
	if err != nil {
		return 0, err
	}
	defer srcFile.Close()

	//獲取源文件的權限
	fi, _ := srcFile.Stat()
	perm := fi.Mode()

	desFile, err := os.OpenFile(des, os.O_CREATE|os.O_RDWR|os.O_TRUNC, perm)
	if err != nil {
		return 0, err
	}
	defer desFile.Close()

	count := 0
	for {
		n, err := srcFile.Read(buf)
		if err != nil && err != io.EOF {
			return 0, err
		}

		if n == 0 {
			break
		}

		if wn, err := desFile.Write(buf[:n]); err != nil {
			return 0, err
		} else {
			count += wn
		}
	}

	return int64(count), nil
}

5. 複製整個文件夾

func CopyDir(srcPath, desPath string) error {
	//檢查目錄是否正確
	if srcInfo, err := os.Stat(srcPath); err != nil {
		return err
	} else {
		if !srcInfo.IsDir() {
			return errors.New("源路徑不是一個正確的目錄!")
		}
	}

	if desInfo, err := os.Stat(desPath); err != nil {
		return err
	} else {
		if !desInfo.IsDir() {
			return errors.New("目標路徑不是一個正確的目錄!")
		}
	}

	if strings.TrimSpace(srcPath) == strings.TrimSpace(desPath) {
		return errors.New("源路徑與目標路徑不能相同!")
	}

	err := filepath.Walk(srcPath, func(path string, f os.FileInfo, err error) error {
		if f == nil {
			return err
		}

		//複製目錄是將源目錄中的子目錄複製到目標路徑中,不包含源目錄本身
		if path == srcPath {
			return nil
		}

		//生成新路徑
		destNewPath := strings.Replace(path, srcPath, desPath, -1)

		if !f.IsDir() {
			CopyFile(path, destNewPath)
		} else {
			if !FileIsExisted(destNewPath) {
				return MakeDir(destNewPath)
			}
		}

		return nil
	})

	return err
}

6. 遍歷指定文件夾中的所有文件(不進入下一級子目錄)

/* 獲取指定路徑下的所有文件,只搜索當前路徑,不進入下一級目錄,可匹配後綴過濾(suffix爲空則不過濾)*/
func ListDir(dir, suffix string) (files []string, err error) {
   files = []string{}

   _dir, err := ioutil.ReadDir(dir)
   if err != nil {
      return nil, err
   }

   suffix = strings.ToLower(suffix)  //匹配後綴

   for _, _file := range _dir {
      if _file.IsDir() {
         continue   //忽略目錄
      }
      if len(suffix) == 0 || strings.HasSuffix(strings.ToLower(_file.Name()), suffix) {
         //文件後綴匹配
         files = append(files, path.Join(dir, _file.Name()))
      }
   }

   return files, nil
}

7. 遍歷指定路徑及其子目錄中的所有文件


/* 獲取指定路徑下以及所有子目錄下的所有文件,可匹配後綴過濾(suffix爲空則不過濾)*/
func WalkDir(dir, suffix string) (files []string, err error) {
	files = []string{}

	err = filepath.Walk(dir, func(fname string, fi os.FileInfo, err error) error {
		if fi.IsDir() {
			//忽略目錄
			return nil
		}

		if len(suffix) == 0 || strings.HasSuffix(strings.ToLower(fi.Name()), suffix) {
			//文件後綴匹配
			files = append(files, fname)
		}

		return nil
	})

	return files, err
}

8. 刪除文件

os.Remove(filename)

9. 刪除文件夾及其包含的所有子目錄和所有文件

os.RemoveAll(dir)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章