ホームページ > バックエンド開発 > Golang > デスクトップを整理する: Go でファイル オーガナイザーを構築します。

デスクトップを整理する: Go でファイル オーガナイザーを構築します。

Mary-Kate Olsen
リリース: 2024-12-05 03:06:14
オリジナル
540 人が閲覧しました

あなたのデスクトップは混沌としていますか?デスクトップやダウンロード ディレクトリにさまざまな種類のファイルが散らかっていませんか?簡単なスクリプトでこれを修正しましょう。

他の go プロジェクトの開始時に行うように、「go mod init」ディレクティブを使用して go.mod ファイルを生成します。物事を簡単にするために、すべてのロジックを main.go ファイルに記述します。

コードを書く前に、スクリプトをどのように動作させたいかについて少し話しましょう。ファイルの種類や作成日を示すディレクトリにファイルを整理できるようにしたいと考えています。つまり、スクリプトでビデオ ファイルをビデオ ディレクトリに、音楽ファイルを音楽ディレクトリなどに並べ替える必要があります。または、特定の日に作成されたすべてのファイルを同じディレクトリに並べ替えます。

それではコードを書いてみましょう:

main.go ファイルを作成し、次のように記述します:

package main

type fileAnalyzer interface {
    analyzeAndSort() error
}

func analyze(fa fileAnalyzer) error {
    return fa.analyzeAndSort()
}
ログイン後にコピー
ログイン後にコピー

プログラムでさまざまな基準でファイルを並べ替えたいため、analyzeAndSort メソッドを定義する fileAnalyzer インターフェイスを作成します。
次に、関数analyzeを作成します。この関数は、fileAnalyzerインターフェイスを実装する構造体を引数として受け取り、analyzeAndSortメソッドを実行します。

このプログラムで説明するような場合には、移動したくない特定のファイルが存在する可能性があります。たとえば、スクリプトのテスト中に、プログラムが go ファイルや実行可能ファイル/バイナリを別のディレクトリに移動することは望ましくありません。これを防ぐには、触れずに残したいすべてのファイルを含むブラックリストを作成する必要があります。

main.go ファイルに次のように記述します:

var blacklist = []string{
    "go",
    "mod",
    "exe",
    "ps1",
}
ログイン後にコピー
ログイン後にコピー

ここでは、並べ替えずに残しておきたいファイルの拡張子を追加しました。 「.go」と「.mod」は go ファイルの拡張子です。私は Windows マシンを使用しているため、バイナリの拡張子は「.exe」になります。ご覧のとおり、私は開発中に PowerShell スクリプトを使用するのが好きなので、「.ps1」も含めました。

次に、いくつかのヘルパー関数を作成します。

func getFileExtension(name string) string {
    return strings.TrimPrefix(filepath.Ext(name), ".")
}

func listFiles(dirname string) ([]string, error) {
    var files []string

    list, err := os.ReadDir(dirname)
    if err != nil {
        return nil, err
    }

    for _, file := range list {
        if !file.IsDir() {
            files = append(files, file.Name())
        }
    }

    return files, nil
}

func listDirs(dirname string) ([]string, error) {
    var dirs []string

    list, err := os.ReadDir(dirname)
    if err != nil {
        return nil, err
    }

    for _, file := range list {
        if file.IsDir() {
            dirs = append(dirs, file.Name())
        }
    }

    return dirs, nil
}

func mkdir(dirname string) error {
    err := os.Mkdir(dirname, 0644)

    if err != nil && os.IsExist(err) {
        return nil
    }

    var e *os.PathError

    if err != nil && errors.As(err, &e) {
        return nil
    }

    return err
}

func moveFile(name string, dst string) error {
    return os.Rename(name, filepath.Join(dst, name))
}

func getCurrentDate(t time.Time) string {
    return t.Format("2006-01-02")
}

func filter[T any](ts []T, fn func(T) bool) []T {
    filtered := make([]T, 0)

    for i := range ts {
        if fn(ts[i]) {
            filtered = append(filtered, ts[i])
        }
    }

    return filtered
}
ログイン後にコピー
ログイン後にコピー

これらのほとんどは説明不要ですが、「mkdir」関数について説明したいと思います。 「mkdir」関数は、引数として渡された名前を使用してディレクトリを作成します。ただし、ディレクトリがすでに存在する場合、または「os.PathError」がある場合、この関数はエラーを返しません。

次に、fileAnalyzer インターフェイスを実装する構造体を作成しましょう。

package main

type fileAnalyzer interface {
    analyzeAndSort() error
}

func analyze(fa fileAnalyzer) error {
    return fa.analyzeAndSort()
}
ログイン後にコピー
ログイン後にコピー

fileTypeAnalyzer 構造体には、現在の作業ディレクトリの名前を保持する wd とマッパーの 2 つのプロパティがあります。マッパーのキーは検出されたファイルのタイプになり、その値はキーに関連付けられたファイル拡張子のリストになります。次に、コンストラクター関数を作成し、ファイル タイプとそれに関連するファイル拡張子をマッパーに提供します。自由にファイルの種類と拡張子をリストに追加してください。 anaylyzeAndSort メソッドは、ファイル拡張子をファイル タイプにマップし、ファイル タイプ ディレクトリを作成し、ファイルをそのディレクトリに移動するいくつかのヘルパー関数とメソッドを呼び出します。また、マッパーによってキャプチャされなかったファイルを保持する「misc」フォルダーも追加しました。もちろん、ブラックリストに登録されたファイルは除きます。

また、作成日ごとにファイルを整理できるようにしたいと考えています。 fileAnalyzer インターフェイスを実装し、ファイルを日付ごとに整理する別の構造体を作成しましょう。

var blacklist = []string{
    "go",
    "mod",
    "exe",
    "ps1",
}
ログイン後にコピー
ログイン後にコピー

ロジックの多くは fileTypeAnalyzer のロジックと同じです。主な違いは、マッパーを提供していないことです。代わりに、ファイル情報から作成日を取得し、それに応じてディレクトリを作成します。

次に、メイン関数にすべてをまとめてみましょう:

func getFileExtension(name string) string {
    return strings.TrimPrefix(filepath.Ext(name), ".")
}

func listFiles(dirname string) ([]string, error) {
    var files []string

    list, err := os.ReadDir(dirname)
    if err != nil {
        return nil, err
    }

    for _, file := range list {
        if !file.IsDir() {
            files = append(files, file.Name())
        }
    }

    return files, nil
}

func listDirs(dirname string) ([]string, error) {
    var dirs []string

    list, err := os.ReadDir(dirname)
    if err != nil {
        return nil, err
    }

    for _, file := range list {
        if file.IsDir() {
            dirs = append(dirs, file.Name())
        }
    }

    return dirs, nil
}

func mkdir(dirname string) error {
    err := os.Mkdir(dirname, 0644)

    if err != nil && os.IsExist(err) {
        return nil
    }

    var e *os.PathError

    if err != nil && errors.As(err, &e) {
        return nil
    }

    return err
}

func moveFile(name string, dst string) error {
    return os.Rename(name, filepath.Join(dst, name))
}

func getCurrentDate(t time.Time) string {
    return t.Format("2006-01-02")
}

func filter[T any](ts []T, fn func(T) bool) []T {
    filtered := make([]T, 0)

    for i := range ts {
        if fn(ts[i]) {
            filtered = append(filtered, ts[i])
        }
    }

    return filtered
}
ログイン後にコピー
ログイン後にコピー

ロガーを設定します。 fileAnalyzer 実装に引数として渡す現在の作業ディレクトリを取得します。アプリケーションにフラグとして渡される値を保持するモード変数と、並べ替え方法を制御する switch ステートメントを作成します。最後に、analyze 関数を呼び出し、fileAnalyzer 実装を引数として渡します。

それだけです。バイナリをビルドしてテストしましょう。私は選別機に電話しました。 「go build -o [name]」

を使用して、好きな名前を付けることができます。

これは、さまざまな種類のファイルが散在するフォルダーです:

Organize your desktop: Build a file organizer in Go.

ファイルの種類ごとに整理しましょう:

Organize your desktop: Build a file organizer in Go.

Organize your desktop: Build a file organizer in Go.

ファイル作成日順に整理しましょう:

Organize your desktop: Build a file organizer in Go.

Organize your desktop: Build a file organizer in Go.

おまけとして、Windows マシンを使用していて PowerShell を使用している場合に、プログラムのテストを簡単にするためのスクリプトを次に示します。

task.ps1 ファイルを作成し、次のように入力します:

type fileTypeAnalyzer struct {
    wd     string
    mapper map[string][]string
}

func newFileTypeAnalyzer(wd string) *fileTypeAnalyzer {
    return &fileTypeAnalyzer{
        wd: wd,
        mapper: map[string][]string{
            "video":  {"mp4", "mkv", "3gp", "wmv", "flv", "avi", "mpeg", "webm"},
            "music":  {"mp3", "aac", "wav", "flac"},
            "images": {"jpg", "jpeg", "png", "gif", "svg", "tiff"},
            "docs":   {"docx", "csv", "txt", "xlsx"},
            "books":  {"pdf", "epub"},
        },
    }
}

func (f fileTypeAnalyzer) analyzeAndSort() error {
    files, err := listFiles(f.wd)
    if err != nil {
        return fmt.Errorf("could not list files: %w", err)
    }

    if err := f.createFileTypeDirs(files...); err != nil {
        return err
    }

    return f.moveFileToTypeDir(files...)
}

func (f fileTypeAnalyzer) moveFileToTypeDir(files ...string) error {
    dirs, err := listDirs(f.wd)
    if err != nil {
        return fmt.Errorf("could not list directories: %w", err)
    }

    for _, dir := range dirs {
        for _, file := range files {
            if slices.Contains(f.mapper[dir], strings.ToLower(getFileExtension(file))) {
                if err := moveFile(file, dir); err != nil {
                    return err
                }
            }
        }
    }

    files, err = listFiles(f.wd)
    if err != nil {
        return err
    }

    if len(files) == 0 {
        return nil
    }

    files = filter(files, func(f string) bool {
        return !slices.Contains(blacklist, getFileExtension(f))
    })

    for i := range files {
        if err := f.moveToMisc(files[i]); err != nil {
            return err
        }
    }

    return nil
}

func (f fileTypeAnalyzer) moveToMisc(file string) error {
    if err := mkdir("misc"); err != nil {
        return err
    }

    return moveFile(file, "misc")
}

func (f fileTypeAnalyzer) createFileTypeDirs(files ...string) error {
    for ftype, fvalues := range f.mapper {
        for _, file := range files {
            if slices.Contains(fvalues, getFileExtension(file)) {
                if err := mkdir(ftype); err != nil {
                    return fmt.Errorf("could not create folder: %w", err)
                }
            }
        }
    }

    return nil
}
ログイン後にコピー

スクリプトを使用してバイナリをビルドするには:

Organize your desktop: Build a file organizer in Go.

スクリプトを使用してファイルを整理するには:

Organize your desktop: Build a file organizer in Go.

スクリプトを使用してディレクトリを削除するには:

Organize your desktop: Build a file organizer in Go.

以上がデスクトップを整理する: Go でファイル オーガナイザーを構築します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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