golang基于window下实现文件遍历(效率高于filepath.Wlak)

golang基于window下实现文件遍历(效率高于filepath.Wlak)

package main

import (
	"fmt"
	"os"
	"path"
	"path/filepath"
	"syscall"
	"time"
	"unsafe"
)

const MAX_PATH = 260

type FILETIME struct {
	dwLowDateTime  uint32
	dwHighDateTime uint32
}

type WIN32_FIND_DATAW struct {
	dwFileAttributes   uint32
	ftCreationTime     FILETIME
	ftLastAccessTime   FILETIME
	ftLastWriteTime    FILETIME
	nFileSizeHigh      uint32
	nFileSizeLow       uint32
	dwReserved0        uint32
	dwReserved1        uint32
	cFileName          [MAX_PATH]uint16
	cAlternateFileName [14]uint16
	dwFileType         uint32
	dwCreatorType      uint32
	wFinderFlags       uint16
	FileName           string
}
type IndexEntry2 struct {
	Name string
	Path string
	Size uint64
}

var (
	kernel32           = syscall.NewLazyDLL("Kernel32.dll")
	procFindFirstFileW = kernel32.NewProc("FindFirstFileW")
	procFindNextFileW  = kernel32.NewProc("FindNextFileW")
	procFindClose      = kernel32.NewProc("FindClose")
)

type HANDLE uintptr

const (
	FILE_ATTRIBUTE_DIRECTORY = 0x10
)

func FindFirstFileW(lpFileName string, lpFindFileData *WIN32_FIND_DATAW) HANDLE {
	name, _ := syscall.UTF16PtrFromString(lpFileName)
	pathPtr := uintptr(unsafe.Pointer(name))
	handle, _, _ := procFindFirstFileW.Call(pathPtr, uintptr(unsafe.Pointer(lpFindFileData)), 0)
	return HANDLE(handle)
}

func FindNextFileW(hFindFile HANDLE, lpFindFileData *WIN32_FIND_DATAW) bool {
	ret, _, _ := procFindNextFileW.Call(uintptr(hFindFile), uintptr(unsafe.Pointer(lpFindFileData)), 0)
	return ret != 0
}

func FindClose(hFindFile HANDLE) bool {
	ret, _, _ := procFindClose.Call(uintptr(hFindFile))
	return ret != 0
}
func FindFileWin(dir string) []IndexEntry2 {
	list := make([]IndexEntry2, 0)
	var findData WIN32_FIND_DATAW
	globalPath := dir + "\\*"
	hFindFile := FindFirstFileW(globalPath, &findData)
	if hFindFile != 0 {
		defer FindClose(hFindFile)

		for {
			fileName := syscall.UTF16ToString(findData.cFileName[:])
			//文件夾
			if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 {
				if (fileName != "..") && (fileName != ".") {
					subPath := path.Join(dir, fileName)
					list = append(list, FindFileWin(subPath)...)
				}
			} else {
				list = append(list, IndexEntry2{
					Name: fileName,
					Size: uint64(findData.nFileSizeLow) | (uint64(findData.nFileSizeHigh) << 32),
					Path: path.Join(dir, fileName),
				})
			}
			if !FindNextFileW(hFindFile, &findData) {
				break // End of search
			}

		}
	}
	return list
}
func FileWalk(dir string) []IndexEntry2 {
	list := make([]IndexEntry2, 0)
	filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() {
			return nil
		}
		list = append(list, IndexEntry2{
			Path: path,
			Size: uint64(info.Size()),
			Name: info.Name(),
		})
		return nil
	})
	return list
}

func main() {
	startTime := time.Now()
	// Replace the path with the desired directory path
	dir := `E:\`

	fmt.Println(len(FindFileWin(dir)))
	// fmt.Println(len(FileWalk(dir)))
	fmt.Printf("共花费时间 %.3f seconds\n", time.Since(startTime).Seconds())
}

在这里插入图片描述

相关推荐

  1. Python 文件夹所有文件夹文件

    2023-12-26 23:00:03       62 阅读
  2. php文件夹

    2023-12-26 23:00:03       58 阅读
  3. golang】二叉树的

    2023-12-26 23:00:03       41 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-26 23:00:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-26 23:00:03       101 阅读
  3. 在Django里面运行非项目文件

    2023-12-26 23:00:03       82 阅读
  4. Python语言-面向对象

    2023-12-26 23:00:03       91 阅读

热门阅读

  1. 【golang】init()函数是什么时候执行的?

    2023-12-26 23:00:03       57 阅读
  2. rabbitmq的事务实现、消费者的事务实现

    2023-12-26 23:00:03       45 阅读
  3. vue elementUI el-form 数据无法赋值且不报错解决方法

    2023-12-26 23:00:03       51 阅读
  4. ARAM 中断实验

    2023-12-26 23:00:03       51 阅读
  5. TypeScript学习(面试篇)

    2023-12-26 23:00:03       42 阅读
  6. LeetCode 每日一题 Day 23 || 简单数学题

    2023-12-26 23:00:03       60 阅读
  7. Mybatis之什么是Mybatis框架

    2023-12-26 23:00:03       51 阅读
  8. LeetCode——1276. 不浪费原料的汉堡制作方案

    2023-12-26 23:00:03       57 阅读
  9. 为什么Nginx是无状态的,而Redis是有状态的?

    2023-12-26 23:00:03       51 阅读
  10. 深入了解Pandas的数据类型

    2023-12-26 23:00:03       50 阅读