php エディター Xiaoxin が、Goroutine を使用した Zip の構築に関する技術記事を提供しました。この記事では、Goroutine を使用して Zip 操作を同時に実行し、プログラムの効率を向上させる方法を学びます。さらに、範囲外のスライスの問題について説明し、この問題を解決するために容量 4096 のスライスを使用する方法を示します。初心者でも経験豊富な開発者でも、この記事はゴルーチンとスライスに関する知識をより深く理解し、適用するのに役立ちます。一緒に探検しましょう!
アーカイブする必要がある各ファイルを処理するゴルーチンを追加して、zip を構築する機能を改善しようとしています。
しかしそれはパニックに終わりました
パニック: 実行時エラー: スライスが範囲外 [4126:4096
]
ターゲット ディレクトリには 190 個のファイル (500 か月) が含まれています。 何が問題なのか本当に分かりません よろしくお願いいたします
###関数:### リーリーここでエラーが発生しました:
リーリー ###スタックトレース: ###func buildarchive() error { var files []string err := filepath.walk("/tmp/dir-to-zip", func(filepath string, info os.fileinfo, err error) error { if info.isdir() { return nil } if err != nil { fmt.println(err) return err } files = append(files, filepath) return nil }) if err != nil { return err } bundle, err := os.create("/tmp/archive.zip") if err != nil { return err } bundlewriter := zip.newwriter(bundle) var wg sync.waitgroup wg.add(len(files)) for _, filepath := range files { go func(filepath string) { defer wg.done() relpath := strings.trimprefix(filepath, fmt.sprintf("%v/", filepath.dir("/tmp/dir-to-zip"))) bundlefile, err := bundlewriter.create(relpath) if err != nil { fmt.println(err) } fsfile, err := os.open(filepath) if err != nil { fmt.println(err) } _, err = io.copy(bundlefile, fsfile) if err != nil { fmt.println(err) } }(filepath) } wg.wait() err = bundlewriter.close() if err != nil { return err } return nil }Solution
同時使用は安全ではありません。複数のゴルーチンを開始すると、各ゴルーチンが zip エントリ (ファイル) を作成して書き込みます。
Writer.Create()
レコード:
Create は、指定された名前を使用してファイルを zip ファイルに追加します。ファイルの内容を書き込む Writer を返します。
[...]
zip を同時に作成することはできません。アプリケーションがパニックやクラッシュを起こしていない場合でも、各 zip エントリの io.Writer は、同じ基礎となるファイル (または一般的には同じ
io.Writer) に書き込みます。アーカイブも無効である可能性があります。
以上がgoroutine を使用して Zip を構築しています。スライスは範囲外です。容量は 4096 です。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。