성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 제가 큰 실수를 했군요. ^^; Delegate를 통한 Bein...
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>윈도우 탐색기에서 열리지 않는 zip 파일 - The Compressed (zipped) Folder '[...].zip' is invalid.</h1> <p> 이상하군요, 웹 서버 측에서 코드로 압축해 내려준 ZIP 파일이 Windows Explorer에서 다음과 같은 오류를 내며 풀리지 않습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Compressed (zipped) Folders Error Windows cannot complete the extraction. The Compressed (zipped) Folder 'C:\temp\test.zip' is invalid. </pre> <br /> 전에 한 번 유사한 경험을 해봐서,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 자바와 닷넷의 압축 호환 ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/724'>https://www.sysnet.pe.kr/2/0/724</a> C# - Deflate, GZip, Zip ; <a target='tab' href='https://www.sysnet.pe.kr/2/0/723'>https://www.sysnet.pe.kr/2/0/723</a> </pre> <br /> 이번에도 파고 들어보면 해결책이 나오지 않을까 싶어 좀 살펴봤습니다. ^^ <br /> <br /> <hr style='width: 50%' /><br /> <br /> 우선, Alzip이나 PowerShell의 Expand-Archive 명령어로는 잘 풀립니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > PS> <span style='color: blue; font-weight: bold'>Expand-Archive test.zip -DestinationPath c:\temp\test</span> </pre> <br /> 도대체 무슨 차이일까요? 혹시 세세한 ZIP 포맷에 어떤 문제가 있을까 싶어 WSL을 경유해 <a target='tab' href='https://perldoc.perl.org/zipdetails'>zipdetails</a>를 이용해 살펴보면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // 탐색기에서 오류가 발생하는 zip 파일 $ <span style='color: blue; font-weight: bold'>zipdetails /mnt/c/temp/test.zip</span> 000000 LOCAL HEADER #1 04034B50 000004 Extract Zip Spec 14 '2.0' 000005 Extract OS 00 'MS-DOS' 000006 General Purpose Flag 0808 [Bits 1-2] 0 'Normal Compression' [Bit 3] 1 'Streamed' [Bit 11] 1 'Language Encoding' 000008 Compression Method 0008 'Deflated' 00000A Last Mod Time 5632700B 'Wed Jan 18 14:00:22 2023' 00000E CRC 00000000 000012 Compressed Length 00000000 000016 Uncompressed Length 00000000 00001A Filename Length 001D 00001C Extra Length 0000 00001E Filename '/invalid_file/test/unk00.json' 00003B PAYLOAD 001A78 STREAMING DATA HEADER 08074B50 001A7C CRC F95C9612 001A80 Compressed Length 00001A3D 001A84 Uncompressed Length 0000776B 001A88 LOCAL HEADER #2 04034B50 001A8C Extract Zip Spec 14 '2.0' 001A8D Extract OS 00 'MS-DOS' 001A8E General Purpose Flag 0808 [Bits 1-2] 0 'Normal Compression' [Bit 3] 1 'Streamed' [Bit 11] 1 'Language Encoding' 001A90 Compression Method 0008 'Deflated' 001A92 Last Mod Time 5632700C 'Wed Jan 18 14:00:24 2023' 001A96 CRC 00000000 001A9A Compressed Length 00000000 001A9E Uncompressed Length 00000000 001AA2 Filename Length 001D 001AA4 Extra Length 0000 001AA6 Filename '/invalid_file/test/unk01.json' 001AC3 PAYLOAD ...[생략]... </pre> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > // 탐색기에서 오류가 없는 zip 파일 $ <span style='color: blue; font-weight: bold'>zipdetails /mnt/c/temp/test2.zip</span> 0000 LOCAL HEADER #1 04034B50 0004 Extract Zip Spec 14 '2.0' 0005 Extract OS 00 'MS-DOS' 0006 General Purpose Flag 0000 [Bits 1-2] 0 'Normal Compression' 0008 Compression Method 0008 'Deflated' 000A Last Mod Time 56CD5886 'Tue Jun 13 11:04:12 2023' 000E CRC FF16EA5E 0012 Compressed Length 00000109 0016 Uncompressed Length 000001EA 001A Filename Length 000D 001C Extra Length 0000 001E Filename 'testfile1.txt' 002B PAYLOAD 0134 LOCAL HEADER #2 04034B50 0138 Extract Zip Spec 14 '2.0' 0139 Extract OS 00 'MS-DOS' 013A General Purpose Flag 0000 [Bits 1-2] 0 'Normal Compression' 013C Compression Method 0008 'Deflated' 013E Last Mod Time 56CD58D5 'Tue Jun 13 11:06:42 2023' 0142 CRC 1D1EC9E8 0146 Compressed Length 00000381 014A Uncompressed Length 000004B8 014E Filename Length 000D 0150 Extra Length 0000 0152 Filename 'testfile2.txt' 015F PAYLOAD ...[생략]... </pre> <br /> 열리지 않는 파일이 "STREAMING DATA HEADER"를 가지고 있습니다. 과연 이게 문제일까요?<br /> <br /> <hr style='width: 50%' /><br /> <br /> 자, 그래서 테스트를 해봤습니다. 이를 위해 다음의 Q&A에 있는 C# 코드를 이용해,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .net core unzip a file and zip subfolder ; <a target='tab' href='https://stackoverflow.com/questions/53645337/net-core-unzip-a-file-and-zip-subfolder'>https://stackoverflow.com/questions/53645337/net-core-unzip-a-file-and-zip-subfolder</a> </pre> <br /> 문제가 되었던 test.zip 파일을 <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/api/system.io.compression.ziparchive'>ZipArchive</a>로 열어, 그대로 다시 ZipArchive로 복사해 저장하는 역할만 하도록 바꿀 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System.IO.Compression; namespace ConsoleApp1; // <a target='tab' href='https://stackoverflow.com/questions/53645337/net-core-unzip-a-file-and-zip-subfolder'>https://stackoverflow.com/questions/53645337/net-core-unzip-a-file-and-zip-subfolder</a> internal class Program { static void Main(string[] args) { using (MemoryStream srcMemoryStream = new MemoryStream()) using (MemoryStream targetMemoryStream = new MemoryStream()) { using (FileStream sourceZipFile = new FileStream(@"C:\temp\test.zip", FileMode.Open)) { sourceZipFile.CopyTo(srcMemoryStream); } using (ZipArchive srcArchive = new ZipArchive(srcMemoryStream, ZipArchiveMode.Read)) using (ZipArchive destArchive = new ZipArchive(targetMemoryStream, ZipArchiveMode.Create, true)) { srcArchive.Entries .ToList() .ForEach((entry) => { ZipArchiveEntry newEntry = destArchive.CreateEntry(entry.FullName); using (Stream srcEntry = entry.Open()) { using (Stream destEntry = newEntry.Open()) { srcEntry.CopyTo(destEntry); } } }); } using (FileStream fs = new FileStream(@"c:\temp\test3.zip", FileMode.Create)) { targetMemoryStream.WriteTo(fs); targetMemoryStream.Flush(); fs.Flush(true); } } } } </pre> <br /> 위의 결과로 저장된 test3.zip 파일은 윈도우 탐색기에서도 잘 열렸던 포맷 유형으로 바뀝니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > $ <span style='color: blue; font-weight: bold'>zipdetails /mnt/c/temp/test3.zip</span> 000000 LOCAL HEADER #1 04034B50 000004 Extract Zip Spec 14 '2.0' 000005 Extract OS 00 'MS-DOS' 000006 General Purpose Flag 0000 [Bits 1-2] 0 'Normal Compression' 000008 Compression Method 0008 'Deflated' 00000A Last Mod Time 56E37165 'Mon Jul 3 14:11:10 2023' 00000E CRC F95C9612 000012 Compressed Length 00001A95 000016 Uncompressed Length 0000776B 00001A Filename Length 001D 00001C Extra Length 0000 00001E Filename '/invalid_file/test/unk00.json' 00003B PAYLOAD 001AD0 LOCAL HEADER #2 04034B50 001AD4 Extract Zip Spec 14 '2.0' 001AD5 Extract OS 00 'MS-DOS' 001AD6 General Purpose Flag 0000 [Bits 1-2] 0 'Normal Compression' 001AD8 Compression Method 0008 'Deflated' 001ADA Last Mod Time 56E37165 'Mon Jul 3 14:11:10 2023' 001ADE CRC 3A6DE765 001AE2 Compressed Length 00001487 001AE6 Uncompressed Length 000061E2 001AEA Filename Length 001D 001AEC Extra Length 0000 001AEE Filename '/invalid_file/test/unk01.json' </pre> <br /> 그리고, 이렇게 변형된 파일 역시 윈도우 탐색기에서는 열리지 않았습니다. 다른 문제가 있다는 것이죠? ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> 본문의 예제 파일을 눈여겨보신 분이라면, "Filename"의 시작이 "/"로 되는 특징을 하나 발견할 수 있습니다. 실제로 이것 때문인지 (Windows 10부터 포함된) tar.exe로 test.zip 파일을 풀어보면 이런 메시지가 하나 보입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp> <span style='color: blue; font-weight: bold'>tar -xf test.zip</span> tar: Removing leading '/' from member names </pre> <br /> 그러니까, 아마도 윈도우 탐색기는 리눅스의 "/" 루트로 시작하는 절대 경로가 있는 파일이라면 정상적으로 해석을 못하는 것이 아닌가 싶은데요, 실제로 이 확인을 우리가 만든 소스 코드에서 "/" 루트 경로를 삭제하는 코드를 추가하면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <span style='color: blue; font-weight: bold'>string filePath = entry.FullName.TrimStart('/');</span> ZipArchiveEntry newEntry = destArchive.CreateEntry(filePath); </pre> <br /> 새롭게 저장한 zip 파일은 탐색기로 잘 열립니다. 그렇다면 반대로, 탐색기에서 압축한 파일을 위의 소스 코드에서 루트 문자를 추가해 다시 저장하는 식으로 바꾸면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <span style='color: blue; font-weight: bold'>string filePath = "/" + entry.FullName;</span> // The Compressed (zipped) Folder '[...].zip' is invalid. ZipArchiveEntry newEntry = destArchive.CreateEntry(filePath); </pre> <br /> 탐색기로는 열리지 않는 zip 파일이 나옵니다. (<a target='tab' href='https://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=2095&boardid=331301885'>이 글에 첨부한 invalid_sample.zip</a>은 그렇게 만든 것입니다.)<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1524
(왼쪽의 숫자를 입력해야 합니다.)