के लिए पर्याप्त एक ज़िप संग्रह के सदस्यों की संख्या की गणना करने के लिए किया जाएगा अजगर में संग्रह:
#!/usr/bin/env python
import sys
from contextlib import closing
from zipfile import ZipFile
with closing(ZipFile(sys.argv[1])) as archive:
count = len(archive.infolist())
print(count)
यह, यदि उपलब्ध zlib
, bz2
, lzma
मॉड्यूल का उपयोग संग्रह को संपीड़ित कर सकते हैं।
एक tar संग्रह में नियमित रूप से फ़ाइलों की संख्या की गणना करने के लिए:
#!/usr/bin/env python
import sys
import tarfile
with tarfile.open(sys.argv[1]) as archive:
count = sum(1 for member in archive if member.isreg())
print(count)
यह अजगर के संस्करण के आधार gzip
, bz2
और lzma
संपीड़न समर्थन कर सकते हैं।
आपको एक तृतीय-पक्ष मॉड्यूल मिल सकता है जो 7z अभिलेखागार के लिए समान कार्यक्षमता प्रदान करेगा।
7z
सुविधा का उपयोग भी एक संग्रह में फ़ाइलों की संख्या प्राप्त करने के लिए:
import os
import subprocess
def count_files_7z(archive):
s = subprocess.check_output(["7z", "l", archive], env=dict(os.environ, LC_ALL="C"))
return int(re.search(br'(\d+)\s+files,\s+\d+\s+folders$', s).group(1))
यहाँ संस्करण है कि कम स्मृति का उपयोग कर सकते अगर वहाँ संग्रह में कई फाइलों हैं:
import os
import re
from subprocess import Popen, PIPE, CalledProcessError
def count_files_7z(archive):
command = ["7z", "l", archive]
p = Popen(command, stdout=PIPE, bufsize=1, env=dict(os.environ, LC_ALL="C"))
with p.stdout:
for line in p.stdout:
if line.startswith(b'Error:'): # found error
error = line + b"".join(p.stdout)
raise CalledProcessError(p.wait(), command, error)
returncode = p.wait()
assert returncode == 0
return int(re.search(br'(\d+)\s+files,\s+\d+\s+folders', line).group(1))
उदाहरण:
import sys
try:
print(count_files_7z(sys.argv[1]))
except CalledProcessError as e:
getattr(sys.stderr, 'buffer', sys.stderr).write(e.output)
sys.exit(e.returncode)
एक सामान्य उपप्रक्रिया के उत्पादन में लाइनों की संख्या की गणना करने के लिए:
from functools import partial
from subprocess import Popen, PIPE, CalledProcessError
p = Popen(command, stdout=PIPE, bufsize=-1)
with p.stdout:
read_chunk = partial(p.stdout.read, 1 << 15)
count = sum(chunk.count(b'\n') for chunk in iter(read_chunk, b''))
if p.wait() != 0:
raise CalledProcessError(p.returncode, command)
print(count)
यह असीमित उत्पादन का समर्थन करता है।
Could you explain why buffsize=-1 (as opposed to buffsize=1 in your previous answer: stackoverflow.com/a/30984882/281545)
bufsize=-1
साधन bufsize=0
(unbuffered) के बजाय डिफ़ॉल्ट आई/ओ बफर आकार अजगर 2. पर यह अजगर 2. पर एक प्रदर्शन को बढ़ावा देने यह हाल अजगर 3 संस्करणों पर डिफ़ॉल्ट है का उपयोग करें। यदि आपको कुछ पहले पायथन 3 संस्करणों पर bufsize
bufsize=-1
में बदला नहीं गया है, तो आपको एक संक्षिप्त पढ़ा जा सकता है (डेटा खोना)।
यह उत्तर भाग में पढ़ता है और इसलिए स्ट्रीम पूरी तरह से दक्षता के लिए buffered है। The solution you've linked लाइन उन्मुख है। bufsize=1
का मतलब है "लाइन buffered"। अन्यथा bufsize=-1
से न्यूनतम अंतर होता है।
and also what the read_chunk = partial(p.stdout.read, 1 << 15) buys us ?
यह read_chunk = lambda: p.stdout.read(1<<15)
के बराबर है, लेकिन सामान्य रूप में और अधिक आत्मनिरीक्षण प्रदान करता है। इसका उपयोग implement wc -l
in Python efficiently पर किया जाता है।
कौन सा संग्रह के प्रकार आप करने वाले हैं समर्थन? –
ज़िप के लिए, टैर चेक https://docs.python.org/2/library/zipfile.html और https://docs.python.org/2/library/tarfile.html –
@ LoïcFaure-Lacroix: धन्यवाद - संपादित किया गया। मुझे निश्चित रूप से 7z की आवश्यकता है ... –