dir_windows.go 4.3 KB

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