When inspecting a ZIP archive supplied by another tool, the unit of investigation is an entry, not a filename. Two entries can carry the same name, so keep an entry reference while you count names and examine contents.
Count the repeated names
Open the existing archive for reading and collect its entries with infolist(). Count their filenames, then keep only counts above one. Counter accepts the names as an iterable. The code in the next section performs this count before reading any payloads.
A count of two means that the archive lists that name twice. It says nothing about whether the contents match or why the entries were added. Keep the entry list even after producing a count: if you later need to inspect both occurrences, a mapping keyed only by name cannot represent them separately.
Sources: Python documentation: zipfile — ZipFile objects — class zipfile.ZipFile, Python documentation: zipfile — ZipFile objects — ZipFile.infolist(), Python documentation: collections.Counter — Counter objects — class collections.Counter
Read and retain every occurrence
This example labels each entry by its position in the returned list and stores its bytes with that label. It reads through each listed ZipInfo object, so repeated filenames remain separate in records. Replace archive.zip with your archive path.
from collections import Counter from zipfile import ZipFile with ZipFile('archive.zip', 'r') as zf: infos = zf.infolist() counts = Counter(info.filename for info in infos) duplicates = {name: count for name, count in counts.items() if count > 1} records = [] for position, info in enumerate(infos): if info.is_dir(): continue with zf.open(info) as member: data = member.read() records.append((position, info.filename, data))
The directory check leaves directory entries out of the content records; the name count still covers the full entry list. Each tuple retains the bytes from one file entry. This approach holds all those bytes in memory. If you only need to inspect each member once, perform that inspection inside the loop and keep a short result in place of data. The important choice is to pass info, rather than its filename, to open().
Sources: Python documentation: zipfile — ZipFile objects — ZipFile.infolist(), Python documentation: zipfile — ZipFile objects — ZipFile.open(), Python documentation: zipfile — ZipInfo objects — ZipInfo.is_dir()
Interpret what you found
Start with duplicates to choose names worth examining. Then look up the corresponding tuples in records by filename and position. A report that says “position 7, report.csv” points to a specific listed occurrence; “report.csv” alone does not. Treat the position as a label within this inspection, and retain the ZipInfo object if you plan another read from the open archive.
Compare the stored bytes only if content equality answers your question. A repeated name may contain equal or different bytes; the count does not establish either result. If you need metadata instead, ZipInfo provides fields such as file_size and CRC. State which field you compared and which entries you included, so another developer can understand the finding without assuming that matching metadata proves matching content.
If reading fails, identify the position and filename where it failed. The documentation lists possible decompression problems, including password, CRC, format, and compression issues; a duplicate name by itself does not diagnose one. For help choosing an API for a different lookup task, use the companion article.
Sources: Python documentation: zipfile — ZipInfo objects — ZipInfo.file_size; ZipInfo.CRC, Python documentation: zipfile — Decompression pitfalls — From file itself
Primary sources checked: 2026-10-22. Prepared with AI assistance and a separate evidence review. The synthetic fixture below was tested locally; other guidance is documentation-based. No performance benchmark was performed.
A reproducible duplicate-name example
We ran the following synthetic, in-memory example with Python 3.12.13 on Darwin on 2026-10-22. It created three stored entries with two distinct names. Reading each ZipInfo returned both same.txt payloads separately.
import io, warnings, zipfile
buffer = io.BytesIO()
with warnings.catch_warnings():
warnings.simplefilter("ignore", UserWarning)
with zipfile.ZipFile(buffer, "w") as archive:
archive.writestr("same.txt", b"first")
archive.writestr("same.txt", b"second")
archive.writestr("other.txt", b"third")
with zipfile.ZipFile(io.BytesIO(buffer.getvalue())) as archive:
print(archive.namelist())
for entry in archive.infolist():
print(entry.filename, archive.read(entry))Observed output
['same.txt', 'same.txt', 'other.txt']
same.txt b'first'
same.txt b'second'
other.txt b'third'
Only this three-entry in-memory ZIP_STORED fixture was executed. No extraction, encrypted or corrupted archives, other Python versions, or performance tests.
댓글 없음:
댓글 쓰기