ホームページ >バックエンド開発 >Golang >goroutine を使用して Zip を構築しています。スライスは範囲外です。容量は 4096 です。

goroutine を使用して Zip を構築しています。スライスは範囲外です。容量は 4096 です。

王林
王林転載
2024-02-09 16:27:081101ブラウズ

使用 goroutine 构建 Zip,切片超出范围,容量为 4096

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

同時使用は安全ではありません。複数のゴルーチンを開始すると、各ゴルーチンが zip エントリ (ファイル) を作成して書き込みます。 Writer.Create()

レコード: Create は、指定された名前を使用してファイルを zip ファイルに追加します。ファイルの内容を書き込む Writer を返します。 [...]

次の Create、CreateHeader、または Close の呼び出しの前に、ファイルの内容を io.Writer に書き込む必要があります。

zip を同時に作成することはできません。アプリケーションがパニックやクラッシュを起こしていない場合でも、各 zip エントリの io.Writer は、同じ基礎となるファイル (または一般的には同じ

io.Writer

) に書き込みます。アーカイブも無効である可能性があります。

以上がgoroutine を使用して Zip を構築しています。スライスは範囲外です。容量は 4096 です。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はstackoverflow.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。