Maison >développement back-end >Golang >Organisez vos téléchargements dans GO

Organisez vos téléchargements dans GO

Linda Hamilton
Linda Hamiltonoriginal
2024-10-31 05:44:301034parcourir

Organizador de seus downloads em GO

Bonjour, ions encore ici.

La peur d’apprendre quelque chose qu’une IA accomplira un jour me laisse complètement angoissée. Mais, si « résoudre des problèmes » est encore une exigence imposée aux êtres humains du futur, pourquoi ne pas persister ?

Cette fois, j'apporte un autre tutoriel. Moins inutile que le premier. Définissons donc les structures des « problèmes », car on sait déjà une chose : ceux qui n'ont pas de problèmes, c'est parce qu'ils n'ont pas assez regardé. Et pour ceux qui ne les ont pas encore trouvés, ce n'est qu'une question de temps avant qu'ils puissent les créer.

Structure du projet

La structure la plus simple du programme est :

  • Scanner un dossier (par exemple le dossier des téléchargements ou un autre répertoire)
  • Identifier le type de chaque fichier dans le répertoire en question
  • Déplacez le fichier vers un sous-dossier correspondant à son type (images, vidéos, documents...)

Démarrage du projet

Créez un répertoire et accédez-y :

mkdir organizador
cd organizador

Créez un fichier organiser.go et démarrez ses modules :

touch organizador.go
go mod init organizador.go

Vous devriez avoir quelque chose comme ça plus ou moins :

~/organizador
.
├── go.mod
└── organizador.go

Partie 1 : Vérifier si un répertoire existe

Définissons le répertoire sourcedirOrigem dans lequel nous allons effectuer l'organisation. Une fois défini, vérifions s'il existe réellement, sinon nous renverrons une erreur :

package main

import (
    "fmt"
    "os"
)

// Defina o deretório o qual você quer organizar como variável global
var dirOrigem string := "/Users/User/Downloads" // Troque o diretório 

func main() {

    // Verificar se o diretório existe, caso contrário, retornar erro
    if _, err := os.Stat(dirOrigem); os.IsNotExist(err) {
        fmt.Println("BAD DIR :( \nDiretório não encontrado: ", dirOrigem)
        return
    } else {
        // Imprimir mensagem caso o diretório exista
        fmt.Println("GOOD DIR :) \nDiretório encontrado: ", dirOrigem)
    }
}

Maintenant, faisons quelques considérations sur le code ci-dessus :

  • La fonction os.Stat renvoie deux valeurs de type os.FileInfo et error err.
  1. FileInfo est une interface qui renvoie des informations détaillées sur le fichier, dont nous n'avons pas besoin dans ce cas. Par conséquent, pour ignorer cette interface, nous utilisons _,. Cependant, nous ne voulons pas ignorer l'erreur : if _, err := ...
  2. Nous passons l'erreur err en paramètre à la fonction os.IsNotExist(), car si le répertoire n'existe pas, la fonction os.Stat() renverra une erreur NOT NULL, provoquant l'erreur os.IsNotExist() renvoie true, exécutant notre message : BAD DIR :(
  3. Si os.IsNotExist() renvoie false, nous imprimerons le message de la condition else : GOOD DIR :)

Partie 2 : Le concept de la fonction de rappel est fou, mec !

Avez-vous remarqué qu'ici, nous y allons petit à petit et profitons des bits et des octets au son du clavier mécanique. _Tchaka tchaka boum ! _

Et maintenant nous allons créer une fonction de rappel. Quelque chose que je n'avais jamais réellement entendu parler, ou que je n'ai jamais été assez curieux pour me demander si j'avais déjà utilisé ce concept dans un code Python dans ma vie avant Golang.

Une fonction de rappel est une fonction passée avec un argument à une autre fonction.

Si vous connaissez déjà le concept, bravo, sinon, bravo. En d’autres termes, félicitations !

Créons maintenant une fonction de rappel filepath.Walk qui sera passée en argument à une autre fonction.

mkdir organizador
cd organizador
touch organizador.go
go mod init organizador.go

Mais attendez, comment filepath.Walk appelle-t-il la fonction de rappel ?

Lorsque vous appelez filepath.Walk(sourcedir, listFiles), la fonction filepath.Walk fait le gros du travail en parcourant tous les fichiers et sous-répertoires de sourcedir.

Pour chaque fichier ou répertoire trouvé, il appelle la fonction listFiles avec trois arguments :

  • chemin : le chemin complet du fichier ou du répertoire actuel.
  • info : un objet os.FileInfo qui contient des informations sur le fichier/répertoire (telles que le nom, s'il s'agit d'un répertoire, la taille, etc.).
  • err : une erreur, si quelque chose ne va pas lors de l'accès à ce fichier ou répertoire.

Go comprend automatiquement que listFiles doit recevoir ces trois paramètres car filepath.Walk attend une fonction qui suit exactement cette signature :

~/organizador
.
├── go.mod
└── organizador.go

Remarquez que la fonction Walk renvoie une erreur ! C'est pertinent !

C'est pourquoi nous assimilons notre fonction filepath.Walk(dirOrigem,listarArquivos) à une erreur :

package main

import (
    "fmt"
    "os"
)

// Defina o deretório o qual você quer organizar como variável global
var dirOrigem string := "/Users/User/Downloads" // Troque o diretório 

func main() {

    // Verificar se o diretório existe, caso contrário, retornar erro
    if _, err := os.Stat(dirOrigem); os.IsNotExist(err) {
        fmt.Println("BAD DIR :( \nDiretório não encontrado: ", dirOrigem)
        return
    } else {
        // Imprimir mensagem caso o diretório exista
        fmt.Println("GOOD DIR :) \nDiretório encontrado: ", dirOrigem)
    }
}

Après tout, parce qu'il renvoie une erreur, c'est une erreur XD

Exemple en action

Voici un aperçu plus détaillé de ce qui se passe à chaque étape :

func main() { 
// Restante do código
.
.
.

// Percorrer e listar os arquivos no diretório dirOrigem
    err := filepath.Walk(dirOrigem, listarArquivos)
    if err != nil {
        fmt.Println("Erro ao percorrer o diretório: ", err)
    }
}

Pour chaque fichier ou répertoire de dirOrigem, filepath.Walk appellera listFiles comme s'il s'agissait de quelque chose comme ceci :

// Função que lista os arquivos do diretório
func listarArquivos(caminho string, info os.FileInfo, err error) error {
    if err != nil {
        return err
    }

    // Ignorar diretórios e exibir apenas arquivos
    if !info.IsDir() && !strings.HasPrefix(info.Name(), ".") {
        fmt.Println("Arquivo encontrado: ", info.Name())
    }
    return nil
}

Dans cet exemple, pour chaque appel :

  • path : reçoit le chemin du fichier ou du répertoire.
  • info : contient des informations sur cet élément (telles que le nom et le type).
  • err : est utilisé pour détecter toute erreur spécifique lors de l'accès au fichier/répertoire.

Fonction de rappel

listFiles est une fonction de rappel que filepath.Walk appelle automatiquement avec ces valeurs. De cette façon, nous n'avons pas à nous soucier de définir les valeurs de chemin, d'information et d'erreur ; filepath.Walk le fait déjà pour nous.

PHE !

Maintenant, faites ce test coquin sur votre terminal :

// Função Walk()
func Walk(root string, walkFn WalkFunc) error

// Tipo WalkFunc
type WalkFunc func(path string, info os.FileInfo, err error) error

Vous pouvez avoir le résultat :

err := filepath.Walk(dirOrgiem, listarArquivos)

Ou :

//Percorrer e listar os arquivos no diretório
err := filepath.Walk(dirOrigem, listarArquivos)

Dans ce cas, j'ai juste mis un "s" supplémentaire dans "Téléchargements" pour que le répertoire Origin soit incorrect.

Supprimez maintenant la fonction listFiles, car nous n'allons pas l'utiliser.

Je plaisante, on va juste changer son nom et ajouter une autre logique.

PARTIE 3 : ORGANISER != ORGANISÉ

Organisé c'est bien, organiser c'est génial.

Après cette brillante observation de ma part, passons à la partie qui nous intéresse vraiment : organiser le tout.

Comme ironie de la vie, avant d'organiser les dossiers, il faut organiser nos idées pour les prochaines étapes.

Notre prochaine fonction a essentiellement besoin de :

  • Créez des sous-dossiers basés sur les extensions de chaque fichier de notre répertoire dirOrigem, s'il n'existe pas.
  • Déplacez les fichiers vers leurs dossiers respectifs en fonction de leurs extensions.
  • Mais si les fichiers sont déjà dans les sous-dossiers d'organisation, il ne faut pas les créer à nouveau.

Comprenons ce que fait chaque partie de ce code :

mkdir organizador
cd organizador

Structure de la fonction organiseFiles

La fonction organiseFiles est appelée pour chaque fichier ou dossier trouvé dans la structure de répertoires. Il vérifie les conditions pour organiser chaque fichier en fonction de son extension, créant des sous-dossiers et déplaçant les fichiers si nécessaire.

touch organizador.go
go mod init organizador.go

Ici, la fonction organiseFiles prend trois paramètres :

  • path : le chemin complet du fichier ou du répertoire actuel.
  • info : informations sur le fichier ou le répertoire, obtenues à partir du type os.FileInfo.
  • err : une erreur possible qui peut survenir lors de la tentative d'accès à l'élément.

La première vérification est de savoir s'il y a une erreur lors de l'accès au fichier/répertoire. Si tel est le cas, il est restitué immédiatement.

Filtrage des fichiers et ignorer les répertoires cachés

~/organizador
.
├── go.mod
└── organizador.go

Cet extrait effectue deux vérifications :

  • !info.IsDir() : vérifie si l'élément n'est pas un répertoire (c'est-à-dire s'il s'agit d'un fichier).
  • !strings.HasPrefix(info.Name(), ".") : vérifie que le nom du fichier ne commence pas par ".", en ignorant les fichiers cachés sur les systèmes basés sur Unix.

Si les deux conditions sont remplies, le fichier s'affiche avec fmt.Println.

Identification de l'extension du fichier et création du nom du sous-dossier

package main

import (
    "fmt"
    "os"
)

// Defina o deretório o qual você quer organizar como variável global
var dirOrigem string := "/Users/User/Downloads" // Troque o diretório 

func main() {

    // Verificar se o diretório existe, caso contrário, retornar erro
    if _, err := os.Stat(dirOrigem); os.IsNotExist(err) {
        fmt.Println("BAD DIR :( \nDiretório não encontrado: ", dirOrigem)
        return
    } else {
        // Imprimir mensagem caso o diretório exista
        fmt.Println("GOOD DIR :) \nDiretório encontrado: ", dirOrigem)
    }
}

Ici :

  • strings.ToLower(filepath.Ext(info.Name())) : extrait l'extension du fichier (par exemple .txt) et la transforme en minuscules pour assurer la cohérence.
  • subfolder := filepath.Join(sourcedir, extension[1:]) : crée le chemin complet du sous-dossier où le fichier sera déplacé. L'extension[1:] supprime le point de départ (.) de l'extension, formant le nom du sous-dossier, tel que txt.

Créer le sous-dossier s'il n'existe pas déjà

func main() { 
// Restante do código
.
.
.

// Percorrer e listar os arquivos no diretório dirOrigem
    err := filepath.Walk(dirOrigem, listarArquivos)
    if err != nil {
        fmt.Println("Erro ao percorrer o diretório: ", err)
    }
}

Ici, la fonction :

  • Vérifiez si le sous-dossier existe déjà en utilisant os.Stat.
  • Si le sous-dossier n'existe pas (os.IsNotExist(err)), il est créé avec os.Mkdir(subfolder, os.ModePerm).
  • os.ModePerm définit les autorisations par défaut pour le nouveau dossier. S'il y a une erreur lors de la création du dossier, celui-ci est affiché et renvoyé.

Définition du chemin de destination du fichier

mkdir organizador
cd organizador

À ce stade, destinationPath représente le chemin final où le fichier sera déplacé. Il est construit en utilisant filepath.Join, pour joindre le chemin du sous-dossier au nom de fichier.

Vérifier si le fichier est déjà dans le dossier de destination

touch organizador.go
go mod init organizador.go
  • Cet extrait compare le chemin de destination avec le chemin du fichier actuel. S'ils sont identiques, cela signifie que le fichier est déjà dans le bon sous-dossier, il est donc ignoré avec un message (fmt.Printf).
  • Sinon, os.Rename(path, destinationPath) déplace le fichier vers le sous-dossier. S'il y a une erreur lors du déplacement, elle est renvoyée.

Résumé final

La fonction :

  1. Faites défiler un répertoire en vérifiant chaque élément.
  2. Ignore les répertoires et fichiers cachés.
  3. Détermine l'extension du fichier et donc le sous-dossier de destination.
  4. Créez le sous-dossier (s'il n'existe pas déjà).
  5. Déplace le fichier vers le sous-dossier sauf s'il s'y trouve déjà.

En utilisant filepath.Walk(dirOrigem, organiseFiles) transmet cette fonction à chaque fichier du répertoire, ce qui entraîne leur organisation automatique.

Ce code s'adapte bien à une fonction d'organisation de fichiers car il gère la logique de création et de déplacement dans une seule fonction – une forme de structure efficace et organisée.

REPO : https://github.com/ionnss/organizador


***Un autre jour sur terre,
ions

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:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn