Maison  >  Article  >  développement back-end  >  Utilisez le nouveau io.FS pour fs.WalkDir et répertoriez les fichiers sur tous les types de systèmes de fichiers

Utilisez le nouveau io.FS pour fs.WalkDir et répertoriez les fichiers sur tous les types de systèmes de fichiers

WBOY
WBOYavant
2024-02-10 10:09:081126parcourir

使用新的 io.FS 到 fs.WalkDir 并列出跨文件系统类型的文件

L'éditeur de PHP recommande d'utiliser le nouveau io.FS pour faire fonctionner le système de fichiers, en particulier lors de l'utilisation de fs.WalkDir et de la liste des fichiers selon les types de systèmes de fichiers. Cette nouvelle fonctionnalité peut gérer les opérations sur les fichiers de manière plus flexible, permettant aux utilisateurs d'obtenir plus facilement les informations sur les fichiers dont ils ont besoin. Que ce soit dans le processus de développement ou de maintenance, cette fonction peut grandement améliorer l'efficacité et réduire les opérations fastidieuses. Si vous souhaitez en savoir plus sur la façon d'utiliser cette fonction, vous souhaiterez peut-être continuer à lire et nous vous présenterons les étapes et précautions détaillées.

Contenu de la question

J'utilise la nouvelle abstraction io.FS pour parcourir le système de fichiers et lire les 128 premiers octets de chaque fichier qui correspondent à notre extension de fichier interne.

Ces fichiers se trouvent dans les systèmes de fichiers locaux et les fichiers d'archives, etc. (ZIP et Tar, je pense).

J'utilise fs.WalkDir, en passant fs.FS (os.DIR et fstest.MapFS dans mes tests). En marchant, je renvoie un ensemble de "fichiers" (en fait, ce sont des fichiers *.pzix et *.pzi, qui sont nos formats propriétaires). Je ne trouve pas de moyen approprié d'utiliser l'interface FS pour obtenir des informations sur le fichier sur lequel je travaille.

Je veux :

  • Obtenir le nom du fichier
  • Obtenir la taille du fichier
  • Obtenir la méthode openfile

Je trouve les interfaces Java/C# dans Go un peu déroutantes. Je souhaite opérer sur l'abstraction, mais je ne sais pas comment obtenir les autres implémentations du fichier lui-même (par exemple l'interface du fichier a Stat() et lit).

La chose la plus simple que j'ai trouvée est de stocker le chemin et le nom de fichier dans un tableau, puis lorsque je parcourt le tableau, de déterminer s'il s'agit de os.Dir ou de fstest.MapFS, mais cela semble plutôt contre-intuitif :

func collectFiles(f fs.FS, root string) []string {
 var files []string
 fs.WalkDir(f, ".", func(p string, d fs.DirEntry, err error) error {
  if !d.IsDir() { // we also check a few other things in the filename here
   f = filepath.Abs(path.Join(root, p))
   files = append(files, f)
  }
 }
 return files
}

Cela me donne :

root = "m://" // mapfs
files = { "m://id-198271.pzi", "m://id-7125-092581.pzix"}

Existe-t-il un moyen plus intelligent pour moi de gérer l'abstraction sans faire ces choses ? Parce qu'après avoir renvoyé le tableau, je dois "ouvrir" le fichier, lire les 128 premiers octets (la signature) et hacher le reste du fichier pour m'assurer qu'il est "valide".

EDIT : Pour clarifier, la méthode collectFiles crée notre liste de résultats de fichiers principale à traiter dans une autre méthode. Je souhaite transmettre les fichiers système locaux, les fichiers zip et les fichiers tar à la méthode afin qu'elle puisse parcourir les fichiers de l'archive et les ajouter à un tableau.

J'aimerais qu'il y ait une interface de fichier que je pourrais stocker dans un tableau au lieu d'une chaîne afin que les appelants suivants puissent faire f.open() sans savoir ce qu'il y a en dessous.

Workaround

p est le nom dans le système de fichiers.

Obtenez la taille en appelant fs.Stat(f, p)

Ouvrez des fichiers en utilisant f.Open(p)

Exemple :

f := os.DirFS("/etc")
fs.WalkDir(f, ".", func(p string, d fs.DirEntry, err error) error {
    if !d.IsDir() {
        st, _ := fs.Stat(f, p)
        r, _ := f.Open(p)
        defer r.Close()

        // Read prefix
        var buf [md5.Size]byte
        n, _ := io.ReadFull(r, buf[:])

        // Hash remainder
        h := md5.New()
        _, _ = io.Copy(h, r)
        s := h.Sum(nil)

        fmt.Printf("%s %d %x %x\n", p, st.Size(), buf[:n], s)
    }
    return nil
})

Par souci de concision, cet exemple ignore les erreurs. Ne faites pas cela dans du vrai code.

https://www.php.cn/link/b599e8250e4481aaa405a715419c8179

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer