dir_windows.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. //go:build windows
  2. package yu_file
  3. import (
  4. yu_math "gogs.qqck.cn/s/tools/math"
  5. yu_sys "gogs.qqck.cn/s/tools/sys"
  6. "strings"
  7. "syscall"
  8. "unsafe"
  9. )
  10. // MkDirs
  11. //
  12. // @Description: 创建多级目录,必须为绝对路径。
  13. func MkDirs(path string) bool {
  14. j_code := yu_sys.SHCreateDirectoryExW.CallUintptr(0, yu_sys.S{yu_sys.Unicode, path}, 0)
  15. return j_code == 0 || j_code == yu_sys.ERROR_FILE_EXISTS || j_code == yu_sys.ERROR_ALREADY_EXISTS
  16. }
  17. // Find
  18. //
  19. // @Description: 基础对象
  20. type Find struct {
  21. // Path 欲搜索的目录
  22. Path string
  23. // Name 欲匹配的文件名,默认为"*"所有,"?"匹配一个任意的字符,"*"匹配无限个任意的字符,包括没有字符,可以组合使用,默认:*
  24. Name string
  25. // Type 0:文件及目录,1:文件、2:目录,默认:0
  26. Type byte
  27. // Start 起始位置,默认:0
  28. Start int
  29. // Count 记录数量,-1为所有,默认:-1
  30. Count int
  31. // Son 是否遍历子目录,默认:false
  32. Son bool
  33. // AddPath 返回结果是否为全路径,默认:false
  34. AddPath bool
  35. }
  36. // NewFind
  37. //
  38. // @Description: 创建 Find 操作对象
  39. func NewFind() (t *Find) {
  40. t = new(Find)
  41. t.SetName("*")
  42. t.SetCount(-1)
  43. return
  44. }
  45. // SetPath
  46. //
  47. // @Description: 设置操作路径
  48. func (t *Find) SetPath(path string) *Find {
  49. if t.Path = path; !strings.HasSuffix(t.Path, `\`) {
  50. t.Path += `\`
  51. }
  52. return t
  53. }
  54. // SetName
  55. //
  56. // @Description: 欲匹配的文件名,默认为"*"所有,"?"匹配一个任意的字符,"*"匹配无限个任意的字符,包括没有字符,可以组合使用,默认:*
  57. func (t *Find) SetName(name string) *Find {
  58. t.Name = name
  59. return t
  60. }
  61. // SetType
  62. //
  63. // @Description: 0:文件及目录,1:文件、2:目录,默认:0
  64. func (t *Find) SetType(Type byte) *Find {
  65. t.Type = Type
  66. return t
  67. }
  68. // SetStart
  69. //
  70. // @Description: 起始位置,默认:0
  71. func (t *Find) SetStart(Start int) *Find {
  72. t.Start = Start
  73. return t
  74. }
  75. // SetCount
  76. //
  77. // @Description: 记录数量,-1为所有,默认:-1
  78. func (t *Find) SetCount(Count int) *Find {
  79. if Count < 0 {
  80. t.Count = yu_math.MaxInt
  81. } else {
  82. t.Count = Count
  83. }
  84. return t
  85. }
  86. // SetSon
  87. //
  88. // @Description: 是否遍历子目录,默认:false
  89. func (t *Find) SetSon(Son bool) *Find {
  90. t.Son = Son
  91. return t
  92. }
  93. // SetAddPath
  94. //
  95. // @Description: 返回结果是否为全路径,默认:false
  96. func (t *Find) SetAddPath(AddPath bool) *Find {
  97. t.AddPath = AddPath
  98. return t
  99. }
  100. // Enum
  101. //
  102. // @Description: 寻找文件
  103. func (t *Find) Enum() []string {
  104. return t.findEnum(t.Path, t.Name, "", t.Start, t.Count)
  105. }
  106. func (t *Find) findEnum(path, name, parent string, start, count int) []string {
  107. j_fileinfo := &yu_sys.FindData{}
  108. j_handle := yu_sys.FindFirstFileW.CallInt(yu_sys.S{yu_sys.Unicode, path + name}, unsafe.Pointer(j_fileinfo))
  109. if j_handle == -1 {
  110. return nil
  111. }
  112. defer yu_sys.FindClose.Call(j_handle)
  113. var j_list []string
  114. for {
  115. if j_filename := unicode_utf8(j_fileinfo.FileName); j_filename != "." && j_filename != ".." {
  116. if (t.Type == 0) || // 文件及目录
  117. (t.Type == 1 && j_fileinfo.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY == 0) || // 文件
  118. (t.Type == 2 && j_fileinfo.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0) { // 目录
  119. if start > 0 {
  120. start--
  121. } else if count > 0 {
  122. count--
  123. if t.AddPath {
  124. j_list = append(j_list, path+j_filename)
  125. } else {
  126. j_list = append(j_list, parent+j_filename)
  127. }
  128. } else {
  129. break
  130. }
  131. }
  132. if t.Son && j_fileinfo.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
  133. j_list = append(j_list, t.findEnum(path+j_filename+"\\", name, parent+j_filename+"\\", start, count)...)
  134. }
  135. }
  136. if !yu_sys.FindNextFileW.CallBool(j_handle, unsafe.Pointer(j_fileinfo)) {
  137. break
  138. }
  139. }
  140. return j_list
  141. }
  142. func unicode_utf8(unicode [520]byte) string {
  143. j_utf8_size := yu_sys.WideCharToMultiByte.CallInt(65001, 0, unicode[:], -1, 0, 0, 0, 0) * 3
  144. j_utf8 := make([]byte, j_utf8_size)
  145. return string(j_utf8[:yu_sys.WideCharToMultiByte.CallInt(65001, 0, unicode[:], -1, j_utf8, j_utf8_size, 0, 0)-1])
  146. }