Tôi có nhiều tệp gz với tổng kích thước khoảng 120GB. Tôi muốn giải nén (gzip) các tệp đó vào cùng một thư mục và xóa tệp gz hiện có. Hiện tại, chúng tôi đang thực hiện thủ công và mất nhiều thời gian hơn để giải nén bằng cách sử dụng gzip -d <filename>
.
Có cách nào tôi có thể giải nén các tệp đó song song bằng cách tạo tập lệnh python hoặc bất kỳ kỹ thuật nào khác không. Hiện tại các tệp này nằm trên máy Linux.Làm thế nào để giải nén nhiều tập tin gz trong python bằng cách sử dụng đa luồng?
Trả lời
Một phần lớn thời gian đồng hồ treo tường dành giải nén tệp với gunzip
hoặc gzip -d
sẽ là từ các hoạt động I/O (đọc và ghi vào đĩa). Nó thậm chí có thể nhiều hơn thời gian thực sự giải nén dữ liệu. Bạn có thể tận dụng điều này bằng cách có nhiều công việc gzip đang chạy trong nền. Vì một số công việc bị chặn trên I/O, một công việc khác có thể thực sự chạy mà không phải đợi trong hàng đợi.
Bạn có thể tăng tốc độ giải nén toàn bộ tệp bằng cách có nhiều quá trình gunzip
chạy trong nền. Mỗi phân phát một tập hợp tệp cụ thể.
Bạn có thể nạp tiền dễ dàng bằng BASH. Chia danh sách tập tin thành các lệnh riêng biệt và sử dụng &
để khởi động nó làm công việc nền. Sau đó, wait
cho mỗi công việc để hoàn thành.
Tôi khuyên bạn nên có từ 2 đến 2 * N công việc cùng một lúc. Trong đó N là số lõi hoặc bộ xử lý logic trên máy tính của bạn. Thử nghiệm khi thích hợp để nhận đúng số.
Bạn có thể chuyển một số thứ dễ dàng bằng BASH.
#!/bin/bash
argarray=("[email protected]")
len=${#argarray[@]}
#declare 4 empty array sets
set1=()
set2=()
set3=()
set4=()
# enumerate over each argument passed to the script
# and round robin add it to one of the above arrays
i=0
while [ $i -lt $len ]
do
if [ $i -lt $len ]; then
set1+=("${argarray[$i]}")
((i++))
fi
if [ $i -lt $len ]; then
set2+=("${argarray[$i]}")
((i++))
fi
if [ $i -lt $len ]; then
set3+=("${argarray[$i]}")
((i++))
fi
if [ $i -lt $len ]; then
set4+=("${argarray[$i]}")
((i++))
fi
done
# for each array, start a background job
gzip -d ${set1[@]} &
gzip -d ${set2[@]} &
gzip -d ${set3[@]} &
gzip -d ${set4[@]} &
# wait for all jobs to finish
wait
Trong ví dụ trên, tôi đã chọn 4 tệp cho mỗi công việc và bắt đầu hai công việc riêng biệt. Bạn có thể dễ dàng mở rộng tập lệnh để có nhiều công việc hơn, nhiều tệp hơn cho mỗi quy trình và lấy tên tệp dưới dạng tham số dòng lệnh.
Bạn có thể làm điều này rất dễ dàng với multiprocessing Pools:
import gzip
import multiprocessing
import shutil
filenames = [
'a.gz',
'b.gz',
'c.gz',
...
]
def uncompress(path):
with gzip.open(path, 'rb') as src, open(path.rstrip('.gz'), 'wb') as dest:
shutil.copyfileobj(src, dest)
with multiprocessing.Pool() as pool:
for _ in pool.imap_unordered(uncompress, filenames, chunksize=1):
pass
Mã này sẽ đẻ trứng một vài quy trình, và mỗi quá trình sẽ trích xuất một tập tin tại một thời điểm.
Ở đây tôi đã chọn chunksize=1
, để tránh quá trình trì hoãn nếu một số tệp lớn hơn mức trung bình.
Xin chào Andrea, cảm ơn câu trả lời của bạn. Nếu tôi hiểu chính xác.Chúng tôi đang xử lý 4 tệp cùng một lúc? nếu một tệp được hoàn thành thì nó sẽ chọn tệp tiếp theo (tệp thứ 5) .Xin vui lòng xác nhận. – user3743797
@ user3743797: đúng là –
Cảm ơn bạn đã xác nhận, điều gì sẽ xảy ra nếu tôi không muốn mã hóa các tệp thay vì đi qua vị trí thư mục để nó sẽ nhận tệp.Do hồ bơi.imap_unordered phương pháp chấp nhận vị trí thư mục như đầu vào cho tên tập tin? – user3743797
- 1. Làm cách nào để giải nén tệp .gz bằng PHP?
- 2. Giải nén tập tin ISO bằng cách sử dụng Java
- 3. Zlib trong Ruby để giải nén .gz
- 4. giải nén một tập tin bằng cách sử dụng C#
- 5. giải nén tệp .gz theo lô
- 6. Giải nén tệp .gz bằng C#
- 7. giải nén tệp .gz bằng GZipStream
- 8. Làm cách nào để giải nén/giải nén trong Emacs
- 9. Tôi có thể giải nén và deserialize một tập tin bằng cách sử dụng dòng?
- 10. Làm thế nào để giải nén GZip trong luồng (C#)?
- 11. Giải nén tập tin tar.gz
- 12. Đọc tập tin txt với đa luồng trong python
- 13. Giải nén tập tin bz2 trong R
- 14. Làm thế nào để nén một tập tin cụ thể bằng cách sử dụng đường ống trong Django?
- 15. Đọc một tập tin từ nhiều chủ đề trong python
- 16. Làm thế nào để giải nén chuỗi Gzip trong ruby?
- 17. làm thế nào để ftp nhiều tập tin bằng cách sử dụng kịch bản shell
- 18. R: Chức năng chung để giải nén tập tin
- 19. Làm thế nào để giải nén một tập tin trong Powershell?
- 20. Làm thế nào để giải nén một tập tin trong Ruby on Rails?
- 21. Làm thế nào để giải nén tập tin trong một Heroku Buildpack
- 22. Giải nén tập tin Nupkg bằng dòng lệnh
- 23. Làm thế nào để sử dụng SDK 7z để nén và giải nén một file
- 24. Nhận kích thước không nén của tệp .gz trong python
- 25. Cách giải nén các tập tin tạp chí mongo
- 26. Làm thế nào để giải nén io.ReadCloser?
- 27. giải nén zlib trong python
- 28. Đọc tập tin nhanh nhất trong ứng dụng đa luồng
- 29. Nén bằng Java Giải nén bằng PHP
- 30. đa luồng bằng cách sử dụng iframe
Cảm ơn bạn đã trả lời, nhưng tôi muốn tự động hóa quá trình này. 01 đến 50 vì vậy tôi đang vượt qua 10 tập tin đầu tiên trong một lệnh gzip như khôn ngoan tôi có 5 processes.So tôi muốn tạo một thread cho 5 công việc đầu tiên như khôn ngoan tôi có thể bắt đầu 10 threads.My câu hỏi là nó có thể trong python? – user3743797
Với một chút bash scripting, bạn có thể nhận được điều này. Chuyển đổi các tham số dòng lệnh của tập lệnh bash của bạn thành một mảng. Sau đó chia thành 4 mảng riêng biệt. Mỗi mảng trở thành một cuộc gọi 'gzip -d' riêng biệt. Tôi sẽ xem nếu tôi có thể làm việc gì đó sau này ... – selbie
@ user3743797 - bây giờ nó hoạt động. Bạn có thể gọi 'script.sh * .gz' hoặc nó sẽ thực hiện chính xác những gì bạn muốn. Tôi khuyên bạn nên có tập lệnh trong một thư mục riêng biệt từ tập hợp các tệp bạn muốn hoạt động. – selbie