iso9660_reader.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package isoutils
  15. import (
  16. "fmt"
  17. "io"
  18. "strings"
  19. "github.com/kdomanski/iso9660"
  20. "yunion.io/x/log"
  21. )
  22. // findISO9660File 在ISO9660中查找文件,返回 *iso9660.File
  23. func (r *ISOFileReader) findISO9660File(path string) (*iso9660.File, error) {
  24. if r.format != ISOFormatISO9660 || r.iso9660Img == nil {
  25. return nil, fmt.Errorf("ISO9660格式未初始化")
  26. }
  27. rootDir, err := r.iso9660Img.RootDir()
  28. if err != nil {
  29. return nil, fmt.Errorf("获取根目录失败: %v", err)
  30. }
  31. // 规范化路径
  32. path = strings.Trim(path, "/")
  33. if path == "" {
  34. return rootDir, nil
  35. }
  36. parts := strings.Split(path, "/")
  37. currentDir := rootDir
  38. for i, part := range parts {
  39. if part == "" {
  40. continue
  41. }
  42. // 获取当前目录的子项
  43. children, err := currentDir.GetChildren()
  44. if err != nil {
  45. return nil, fmt.Errorf("读取目录失败: %v", err)
  46. }
  47. // 查找匹配的文件或目录(不区分大小写)
  48. var found *iso9660.File
  49. for _, child := range children {
  50. if strings.EqualFold(child.Name(), part) {
  51. found = child
  52. break
  53. }
  54. }
  55. if found == nil {
  56. return nil, fmt.Errorf("文件或目录不存在: %s", part)
  57. }
  58. // 如果是最后一个部分,返回找到的文件
  59. if i == len(parts)-1 {
  60. return found, nil
  61. }
  62. // 检查是否为目录
  63. if !found.IsDir() {
  64. return nil, fmt.Errorf("路径中的%s不是目录", part)
  65. }
  66. currentDir = found
  67. }
  68. return currentDir, nil
  69. }
  70. // listISO9660Dir 列出ISO9660格式指定目录下的所有文件和子目录
  71. func (r *ISOFileReader) listISO9660Dir(path string) ([]ISO9660FileInfo, error) {
  72. if r.format != ISOFormatISO9660 {
  73. return nil, fmt.Errorf("此方法仅支持ISO9660格式")
  74. }
  75. // 获取目录
  76. dir, err := r.findISO9660File(path)
  77. if err != nil {
  78. return nil, err
  79. }
  80. if !dir.IsDir() {
  81. return nil, fmt.Errorf("路径%s不是目录", path)
  82. }
  83. // 获取子项
  84. children, err := dir.GetChildren()
  85. if err != nil {
  86. return nil, fmt.Errorf("读取目录失败: %v", err)
  87. }
  88. var files []ISO9660FileInfo
  89. for _, child := range children {
  90. fileInfo := ISO9660FileInfo{
  91. Name: child.Name(),
  92. IsDir: child.IsDir(),
  93. Size: child.Size(),
  94. Location: 0, // 使用库时不需要直接访问位置
  95. }
  96. files = append(files, fileInfo)
  97. }
  98. return files, nil
  99. }
  100. // readISO9660FileContent 读取ISO9660格式文件内容
  101. func (r *ISOFileReader) readISO9660FileContent(path string) (string, error) {
  102. file, err := r.findISO9660File(path)
  103. if err != nil {
  104. return "", fmt.Errorf("文件%s不存在: %v", path, err)
  105. }
  106. if file.IsDir() {
  107. return "", fmt.Errorf("路径%s是目录,不是文件", path)
  108. }
  109. reader := file.Reader()
  110. if reader == nil {
  111. return "", fmt.Errorf("无法读取文件%s", path)
  112. }
  113. // 读取前10KB内容(足够识别特征)
  114. buf := make([]byte, 10*1024)
  115. n, err := reader.Read(buf)
  116. if err != nil && err != io.EOF {
  117. log.Errorf("读取ISO9660文件%s失败: %v", path, err)
  118. return "", fmt.Errorf("读取文件%s失败: %v", path, err)
  119. }
  120. return strings.TrimSpace(string(buf[:n])), nil
  121. }