GO でダウンロードを整理する

Linda Hamilton
リリース: 2024-10-31 05:44:30
オリジナル
966 人が閲覧しました

Organizador de seus downloads em GO

こんにちは、イオンです。

AI がいつか達成するであろう何かを学習するのではないかという恐怖で、私は完全に心が痛みます。しかし、「問題を解決する」ことが未来の人類に課せられた要件であるならば、なぜ固執しないのでしょうか?

今回は別のチュートリアルを紹介します。最初のものよりも役に立たない。それでは、「問題」の構造を定義しましょう。なぜなら、私たちはすでに 1 つのことを知っているからです。問題を抱えていない人は、十分に調べていないからです。まだ見つけていない人も、作成できるようになるのは時間の問題です。

プロジェクトの構造

プログラムの最も単純な構造は次のとおりです:

  • フォルダー (ダウンロード フォルダーや別のディレクトリなど) をスキャンします
  • 問題のディレクトリ内の各ファイルのタイプを特定します
  • ファイルをその種類 (画像、ビデオ、ドキュメントなど) に対応するサブフォルダーに移動します

プロジェクトの開始

ディレクトリを作成し、そこに移動します:

mkdir organizador
cd organizador
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

organizer.go ファイルを作成し、そのモジュールを開始します:

touch organizador.go
go mod init organizador.go
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

おおよそ次のようなものが必要です:

~/organizador
.
├── go.mod
└── organizador.go
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

パート 1: ディレクトリが存在するかどうかを確認する

編成を実行するソース ディレクトリ dirOrigem を定義しましょう。定義したら、実際に存在するかどうかを確認してみましょう。存在しない場合はエラーを返します:

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)
    }
}

ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここで、上記のコードについていくつか考慮してみましょう:

  • os.Stat 関数は、タイプ os.FileInfo とエラー err の 2 つの値を返します。
  1. FileInfo は、詳細なファイル情報を返すインターフェイスですが、この場合は必要ありません。したがって、このインターフェイスを無視するには、_, を使用します。ただし、次のエラーは無視したくありません: if _, err := ...
  2. エラー err をパラメータとして os.IsNotExist() 関数に渡します。ディレクトリが存在しない場合、os.Stat() 関数は NOT NULL エラーを返し、 os.IsNotExist() は true を返し、メッセージを実行します: BAD DIR :(
  3. os.IsNotExist() が false を返した場合、else 条件からのメッセージを出力します: GOOD DIR :)

パート 2: コールバック関数の概念はクレイジーです!

ここではメカニカルキーボードの音を少しずつ楽しんでいるのにお気づきでしょうか。 _チャカチャカブーム! _

そして今、コールバック関数を作成します。これは、私が実際に学んだこともなければ、Golang 以前の人生で Python コードでこの概念を使用したことがあるかどうか疑問に思うほど好奇心を持ったこともありませんでした。

コールバック関数は、引数とともに別の関数に渡される関数です。

この概念をすでによく理解している場合は、おめでとうございます。そうでない場合は、おめでとうございます。つまり、おめでとうございます!

次に、別の関数に引数として渡される filepath.Walk コールバック関数を作成しましょう。

mkdir organizador
cd organizador
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
touch organizador.go
go mod init organizador.go
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

しかし、待ってください。filepath.Walk はどのようにしてコールバック関数を呼び出すのでしょうか?

filepath.Walk(sourcedir, listFiles) を呼び出すと、filepath.Walk 関数は、sourcedir 内のすべてのファイルとサブディレクトリをたどるという重労働を実行します。

見つかったファイルまたはディレクトリごとに、次の 3 つの引数を指定して listFiles 関数を呼び出します。

  • パス: 現在のファイルまたはディレクトリへのフルパス。
  • info: ファイル/ディレクトリに関する情報 (名前、ディレクトリであるかどうか、サイズなど) を含む os.FileInfo オブジェクト。
  • err: このファイルまたはディレクトリへのアクセス時に問題が発生した場合のエラー。

Go は、filepath.Walk がまさにこのシグネチャに従う関数を期待しているため、listFiles がこれら 3 つのパラメータを受け取る必要があることを自動的に理解します。

~/organizador
.
├── go.mod
└── organizador.go
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

Walk 関数がエラーを返すことに注意してください。これは関係あります!

これが、関数 filepath.Walk(dirOrigem,listarArquivos) を 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)
    }
}

ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

結局、エラーを返すのでエラーです XD

実際の例

各ステップで何が起こるかを詳しく説明します:

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)
    }
}
ログイン後にコピー
ログイン後にコピー

dirOrigem 内の各ファイルまたはディレクトリに対して、filepath.Walk は次のようなものであるかのように listFiles を呼び出します。

// 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
}
ログイン後にコピー

この例では、各呼び出しに対して次のようになります。

  • パス: ファイルまたはディレクトリのパスを受け取ります。
  • info: このアイテムに関する情報 (名前やタイプなど) が含まれます。
  • err: ファイル/ディレクトリへのアクセス中に特定のエラーを捕捉するために使用されます。

コールバック関数

listFiles は、filepath.Walk がこれらの値を使用して自動的に呼び出すコールバック関数です。こうすることで、パス、情報、エラー値の設定について心配する必要がなくなります。 filepath.Walk はすでにこれを行っています。

ふぇ!

次に、ターミナルでそのいたずらなテストを実行してください:

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

// Tipo WalkFunc
type WalkFunc func(path string, info os.FileInfo, err error) error
ログイン後にコピー

次の結果が得られます:

err := filepath.Walk(dirOrgiem, listarArquivos)
ログイン後にコピー

または:

//Percorrer e listar os arquivos no diretório
err := filepath.Walk(dirOrigem, listarArquivos)
ログイン後にコピー

この場合、Origin ディレクトリが正しくないように、「ダウンロード」に余分な「s」を追加しました。

listFiles 関数は使用しないので、削除します。

冗談ですが、彼女の名前を変更して他のロジックを追加するだけです。

パート 3: 整理する != 整理する

整理整頓は良いことですが、整理整頓は素晴らしいです。

私のこの素晴らしい観察の後、私たちが本当に興味を持っている部分、つまり全体を整理する部分に移りましょう。

人生の皮肉として、ファイルを整理する前に、次のステップに向けてアイデアを整理する必要があります。

次の関数は基本的に次のものが必要です:

  • dirOrigem ディレクトリ内の各ファイルの拡張子に基づいてサブフォルダーを作成します (存在しない場合)。
  • 拡張子に応じて、ファイルをそれぞれのフォルダーに移動します。
  • ただし、ファイルが既に整理サブフォルダーにある場合は、再度作成する必要はありません。

このコードの各部分が何をするのかを理解しましょう:

mkdir organizador
cd organizador
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

OrganizeFiles 関数の構造

organizeFiles 関数は、ディレクトリ構造内で見つかったファイルまたはフォルダーごとに呼び出されます。拡張子に基づいて各ファイルを整理するための条件をチェックし、必要に応じてサブフォルダーを作成し、ファイルを移動します。

touch organizador.go
go mod init organizador.go
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここで、organizeFiles 関数は 3 つのパラメータを取ります:

  • path: 現在のファイルまたはディレクトリへのフルパス。
  • info: ファイルまたはディレクトリの情報。os.FileInfo.
  • タイプから取得されます。
  • err: 項目にアクセスしようとしたときに発生する可能性のあるエラー。

最初のチェックは、ファイル/ディレクトリへのアクセス時にエラーがないかどうかです。その場合は直ちに返却されます。

ファイルのフィルタリングと隠しディレクトリの無視

~/organizador
.
├── go.mod
└── organizador.go
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

このスニペットは 2 つのチェックを行います:

  • !info.IsDir(): 項目がディレクトリではない (つまり、ファイルである) かどうかを確認します。
  • !strings.HasPrefix(info.Name(), "."): Unix ベースのシステム上の隠しファイルを無視して、ファイル名が "." で始まらないことをチェックします。

両方の条件が満たされる場合、ファイルは 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)
    }
}

ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

こちら:

  • strings.ToLower(filepath.Ext(info.Name())): ファイル拡張子 (例: .txt) を抽出し、一貫性を確保するために小文字に変換します。
  • subfolder := filepath.Join(sourcedir, extension[1:]): ファイルの移動先となるサブフォルダーの完全なパスを作成します。 extension[1:] は拡張子から開始点 (.) を削除し、txt.
  • などのサブフォルダーの名前を形成します。

サブフォルダーが存在しない場合は作成します

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)
    }
}
ログイン後にコピー
ログイン後にコピー

ここでの関数:

  • os.Stat.
  • を使用して、サブフォルダーが既に存在するかどうかを確認します。
  • サブフォルダーが存在しない場合 (os.IsNotExist(err))、os.Mkdir(subfolder, os.ModePerm) で作成されます。
  • os.ModePerm は、新しいフォルダーのデフォルトのアクセス許可を設定します。フォルダー作成時にエラーがあった場合は、エラーが表示されて返されます。

ファイルの宛先パスの設定

mkdir organizador
cd organizador
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

この時点で、destinationPath はファイルが移動される最終的なパスを表します。これは、filepath.Join を使用して構築され、サブフォルダーのパスをファイル名に結合します。

ファイルが宛先フォルダーに既に存在するかどうかを確認する

touch organizador.go
go mod init organizador.go
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
  • このスニペットは、宛先パスと現在のファイル パスを比較します。それらが同じ場合は、ファイルがすでに正しいサブフォルダーに存在することを意味するため、メッセージ (fmt.Printf) が表示されて無視されます。
  • それ以外の場合、os.Rename(path, destinationPath) はファイルをサブフォルダーに移動します。移動中にエラーが発生した場合は返されます。

最終的なまとめ

機能:

  1. ディレクトリをスクロールして、各項目を確認します。
  2. 隠しディレクトリとファイルを無視します。
  3. ファイル拡張子、つまり宛先サブフォルダーを決定します。
  4. サブフォルダーを作成します (まだ存在しない場合)。
  5. ファイルが既にサブフォルダーに存在しない限り、ファイルをそのサブフォルダーに移動します。

filepath.Walk(dirOrigem, OrganizeFiles) を使用すると、この関数がディレクトリ内の各ファイルに渡され、すべてのファイルが自動的に整理されます。

このコードは、作成と移動のロジックを 1 つの関数で処理するため、ファイル整理関数として適切です。これは効率的で組織化された構造形式です。

リポジトリ: https://github.com/ionnss/organizador


***地球上の別の日、
イオン

以上がGO でダウンロードを整理するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!