Hello, ions here again.
The fear of learning something that an AI will one day accomplish leaves me completely distressed. But, if "solving problems" is still a requirement imposed on human beings of the future, why not persist?
This time I bring another tutorial. Less useless than the first. So let's define the structures of "problems", because we already know one thing: those who don't have problems, it's because they didn't look enough. And for those who haven't found them yet, it's just a matter of time before they can create them.
The simplest structure of the program is:
Create a directory and navigate to it:
mkdir organizador cd organizador
Create an organizer.go file and start its modules:
touch organizador.go go mod init organizador.go
You should have something more or less like this:
~/organizador . ├── go.mod └── organizador.go
Let's define the source directorydirOrigem in which we will perform the organization. With it defined, let's check if it actually exists, otherwise we will return an error:
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) } }
Now, let's make some considerations about the code above:
Did you notice that here we are going little by little and enjoying the bits and bytes to the sound of the mechanical keyboard. _Tchaka tchaka boom! _
And now we are going to create a callback function. Something that I had never actually learned about, or was never curious enough to question if I ever used this concept in any Python code in my pre-golang life.
A callback function is a function passed with an argument to another function.
If you are already familiar with the concept, congrats, otherwise, congrats. In other words, congrats!
Now let's create a filepath.Walk callback function that will be passed as an argument to another function.
mkdir organizador cd organizador
touch organizador.go go mod init organizador.go
But wait, how does filepath.Walk call the Callback Function?
When you call filepath.Walk(sourcedir, listFiles), the filepath.Walk function does the heavy lifting of walking through all the files and subdirectories within sourcedir.
For each file or directory found, it calls the listFiles function with three arguments:
Go automatically understands that listFiles must receive these three parameters because filepath.Walk expects a function that follows exactly this signature:
~/organizador . ├── go.mod └── organizador.go
Notice that the Walk function returns an error! This is relevant!
That's why we equate our function filepath.Walk(dirOrigem,listarArquivos) to an err:
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) } }
After all, because it returns an error, it is an error XD
Here's a more detailed look at what happens at each step:
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) } }
For each file or directory in dirOrigem, filepath.Walk will call listFiles as if it were something like this:
// 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 }
In this example, for each call:
listFiles is a callback function that filepath.Walk automatically calls with these values. This way, we don't need to worry about setting the path, info and err values; filepath.Walk already does this for us.
PHE!
Now do that naughty test on your terminal:
// Função Walk() func Walk(root string, walkFn WalkFunc) error // Tipo WalkFunc type WalkFunc func(path string, info os.FileInfo, err error) error
You can have the result:
err := filepath.Walk(dirOrgiem, listarArquivos)
Or:
//Percorrer e listar os arquivos no diretório err := filepath.Walk(dirOrigem, listarArquivos)
In this case I just put an extra "s" in "Downloads" so that the Origin dir would be incorrect.
Now delete the listFiles function, as we are not going to use it.
Just kidding, we're just going to change her name and add other logic.
Organized is good, organizing is awesome.
After this brilliant observation on my part, let's move on to the part that really interests us: organizing the whole thing.
As an irony in life, before organizing the files, we have to organize our ideas for the next steps.
Our next function basically needs:
Let's understand what each part of this code does:
mkdir organizador cd organizador
The organizeFiles function is called for each file or folder found in the directory structure. It checks the conditions to organize each file based on its extension, creating subfolders and moving files if necessary.
touch organizador.go go mod init organizador.go
Here, the organizeFiles function takes three parameters:
The first check is whether there is an error when accessing the file/directory. If so, it is returned immediately.
~/organizador . ├── go.mod └── organizador.go
This snippet makes two checks:
If both conditions are met, the file is displayed with fmt.Println.
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) } }
Here:
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) } }
Here, the function:
mkdir organizador cd organizador
At this point, destinationPath represents the final path where the file will be moved. It is constructed using filepath.Join, to join the subfolder path to the filename.
touch organizador.go go mod init organizador.go
The function:
Using filepath.Walk(dirOrigem, organizeFiles) passes this function to each file within the directory, causing them all to be organized automatically.
This code fits well as a file organization function because it handles the creation and movement logic in a single function – an efficient and organized form of structure.
REPO: https://github.com/ionnss/organizador
***Another day on earth,
ions
The above is the detailed content of Organize your downloads in GO. For more information, please follow other related articles on the PHP Chinese website!