질문 님이 쓰신 글 :
: zip 파일 하나 업로드 합니다.
:
: 분명히 "대한민국.txt" 파일하나를 본문내용 없이 압축해서 만들어진 zip 파일인데
: C++ 빌더에 있는 TZipFile을 이용해서 보면 한글이 정상적으로 표시되지 않습니다.
: cp949, utf, cp878 여러가지 방법을 다 사용해 보았지만 안됩니다.
:
: 빌더님이 설명해주신 방법으로 해봐도 마찬가지로 안되는데 어떻게 해결해야할지 모르겠습니다.
:
: void __fastcall TForm1::Button1Click(TObject *Sender)
: {
: std::auto_ptr <TZipFile> z (new TZipFile);
:
: z->Open(L"c:/test_r.zip", zmRead);
:
: for(int i = 0; i < z->FileCount; ++i)
: {
: std::auto_ptr <TEncoding> e (new TMBCSEncoding(0x3B5, 0, 0));
: Memo1->Lines->Add(e->GetString(z->FileInfo[i].FileName));
: }
: }
:
: 근데 신기하게 winrar로 보면 파일명이 제대로 보이거든요.
:
답변:
이전에 올린 답변에서 이미 언급했던 내용인데요...
엠바가 RTL에 구현해 놓은 TZipFile은 확장된 zip file name 엔코딩 방식을 고려하는 코드가 전혀 구현되어 있지 않습니다.
기억하기로 TZipFile이 XE2 부터 제공된 거로 알고있는데, XE7 Update 1 이 나온 지금 까지도 바뀐게 없이 베타도 안되는
알파수준 정도라고나 할까요.
TZipFile에는 zip 파일의 Extra 정보를 고려하는 코드가 전혀 구현되어 있지 않기 때문에.. 직접 구현해 줘야 하는데...
간략하게 아래와 같은 식으로 구현하면 파일네임을 정상적으로 볼수 있을 겁니다.
//---------------------------------------------------------------------------
String parseExtra(int len, void *extra)
{
char *p = (char*)extra;
SHORT i;
AnsiStringT < CP_UTF8 > as;
while(len > 0)
{
i = *(SHORT*)(p + 2);
if(0x7075 == *(SHORT*)p) {
memcpy(as.SetLength(i-5).c_str(), p+9, i-5);
return as;
}
len -= (4+i), p += (4+i);
}
return as;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button1Click(TObject *Sender)
{
std::auto_ptr < TZipFile > z(new TZipFile());
z->Open(L"c:/test_r.zip",zmRead);
String s = parseExtra(z->FileInfo[0].ExtraFieldLength, &z->FileInfo[0].ExtraField[0]);
Memo1->Lines->Add(s);
}
//---------------------------------------------------------------------------
zip 파일이 윈도우즈 플렛폼에서 만들어 졌는지, 아니면 유닉스 플렛폼에서 만들어 졌는지 등의 정보도 알수 있는데...
엠바 TZipFile에는 그런 부분을 고려하는 코드도 전혀 구현되어 있지 않습니다. zip 파일 구조 부터 분석해 보는 게 빠르겠네요.