기술 · 실용 가이드
Python BadZipFile: ZIP 구조·CRC·필수 파일을 구분하세요
PK 시작 바이트, 목록 성공, 무결성 통과는 다른 판단입니다. 복구 전에 원본을 보존하세요.

BadZipFile: File is not a zip file이 나오면 정확한 입력과 전체 예외를 먼저 보관하세요. 메시지만으로 확장자 변경, 캐시 삭제, 바이트 절단이 원하는 ZIP을 복원한다고 판단할 수 없습니다.
구조 판독, CRC 오류 없이 멤버 읽기, 필요한 파일 포함 여부를 세 단계로 구분하세요. 작은 합성 시험 다섯 개는 앞 단계의 성공이 다음 단계의 성공을 대신하지 못함을 보여 줍니다.
1. 실제 입력과 실패 단계를 보존
실제 경로·바이트 크기·SHA-256·Python 버전·전체 예외를 기록하고 원본 대신 사본을 조사하세요. 로컬 해시는 바이트 식별 기록일 뿐입니다. 같은 아티팩트에 대한 독립적이고 신뢰할 수 있는 참조와 비교해야 출처 확인 의미가 있습니다.
다운로드라면 승인된 출처와 버전을 확인하고 저장된 것이 오류·로그인 페이지인지 살펴보세요. ZIP을 생성했다면 쓰기 핸들을 닫은 후 읽어야 합니다. Python 문서는 닫을 때 필수 레코드를 기록한다고 설명합니다. 원본을 w 모드로 열면 잘리므로 피하세요.
2. 구조 확인 후 전체 내용 검사
출처가 알려진 적절히 작은 후보에 zipfile.is_zipfile(path)를 실행한 다음 with zipfile.ZipFile(path, "r") as z로 열어 z.infolist()를 살펴보세요. 이름·file_size·compress_size·compress_type을 기록합니다. 생성자에서 실패하면 목록 성공이 아닙니다. PKWARE는 끝 레코드를 요구하며 PK 두 글자만으로는 부족합니다.
출처와 처리 범위를 검토한 뒤 같은 컨텍스트에서 z.testzip()를 실행하세요. 첫 불량 이름을 반환하며 검사 통과 시 None입니다. 예외는 미해결 결과로 보존하세요. 선언 크기는 참고이며 강제 자원 한도가 아닙니다. 크거나 신뢰할 수 없는 ZIP은 한도를 강제하는 격리 처리 환경이 필요합니다.
3. 다섯 실측 사례 비교
Python3.12.14에서 작은 BytesIO 샘플을 만들었으며 압축 해제는 하지 않았습니다. 정상136바이트는 report.txt를 나열하고 testzip()이 None이었습니다.22바이트 끝 레코드를 빼면114바이트이며 PK로 시작해도 is_zipfile()은 False, 생성자는 BadZipFile이었습니다.
저장된 본문 한 바이트만 바꾸고 CRC를 유지하면 크기는136바이트 그대로입니다. is_zipfile()은 True이고 목록도 보이지만 testzip()은 report.txt를 반환했습니다. 유효한22바이트 빈 ZIP은 True와 None이어도 목록은 비었습니다.20바이트 HTML은 형식 검사에 실패했습니다. 독자의 파일이나 모든 ZIP 기능을 시험한 것은 아닙니다.
4. 확인된 원인에 맞춰 수정 후 내용 검증
형식이 다르거나 불완전하면 정상 승인 경로로 별도 이름의 사본을 받아 정확한 아티팩트 참조와 비교하세요. 생성이 미완료라면 다시 만들고 올바르게 닫습니다. 미지원 압축·암호화 예외는 리더의 지원 범위를 먼저 확인하세요. Python zipfile은 분할 ZIP을 처리하지 않습니다.
해시·구조·CRC 결과·필수 멤버 이름·최종 앱 시험을 기록하세요. CRC 통과는 발행자·무해성·필수 파일 완비를 보증하지 않습니다. 필요한 이름이 없으면 None이어도 완료로 수락하지 마세요. 유일한 원본에 일반적인 시그니처 절단 패치를 적용해도 사라진 본문이 복원되지는 않습니다.
