php 편집자 Xiaoxin이 goroutine을 사용하여 Zip을 빌드하는 방법에 대한 기사를 가져왔습니다. 이 기사에서는 프로그램의 효율성을 높이기 위해 고루틴을 사용하여 Zip 작업을 동시에 수행하는 방법을 알아봅니다. 또한 범위를 벗어난 슬라이스 문제에 대해 논의하고 이 문제를 해결하기 위해 4096 용량의 슬라이스를 사용하는 방법을 보여줍니다. 초보자이든 숙련된 개발자이든 이 글은 고루틴 및 슬라이싱과 관련된 지식을 더 잘 이해하고 적용하는 데 도움이 될 것입니다. 함께 탐험해 보세요!
아카이브해야 하는 각 파일을 처리하는 고루틴을 추가하여 zip을 빌드하는 기능을 개선하려고 합니다.
하지만 패닉상태로 끝났다
panic:运行时错误:切片超出范围[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 }
zip.Writer
동시 사용에는 안전하지 않습니다. 여러 고루틴을 시작하면 각 고루틴은 zip 항목(파일)을 생성하고 씁니다.
Writer.Create()
기록:
Create는 제공된 이름을 사용하여 zip 파일에 파일을 추가합니다. 파일 내용을 써야 하는 Writer를 반환합니다.
[...] 다음번 Create, CreateHeader 또는 Close 호출 전에 파일 내용을 io.Writer에 작성해야 합니다.
동시에 zip을 생성할 수 없습니다. io.Writer
s 写入相同的底层文件(或一般情况下相同的 io.Writer
) 각 zip 항목에 대해 애플리케이션이 당황하거나 충돌하지 않더라도 결과 zip 아카이브가 유효하지 않을 수 있습니다.
위 내용은 고루틴을 사용하여 Zip을 빌드하면 슬라이스가 범위를 벗어났고 용량은 4096입니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!