2013-12-11 3 views
1

다음은 압축 된 파일을 허용하고 한 번에 1024 개의 문자를 읽음으로써 txt 파일로 변환하는 내 기능입니다.Delphi 7 및 Delphi XE4의 압축 풀기

procedure DecompressFile(const ACompressedFile, ADestinationFile : String); 
var 
    SourceStream : TFileStream; 
    DestinationStream : TFileStream; 
    DecompressionStream : TDecompressionStream; 

    nRead : Integer; 
    Buffer: array [0..1023] of Char; 
begin 
    SourceStream := TFileStream.Create(ACompressedFile, fmOpenRead); 
    try 
    DestinationStream := TFileStream.Create(ADestinationFile, fmCreate); 
    try 
     DecompressionStream := TDecompressionStream.Create(SourceStream); 
     try 
     repeat 
      nRead := DecompressionStream.Read(Buffer, 1024); 
      DestinationStream.Write(Buffer, nRead); 
     until nRead = 0; 
     finally 
     DecompressionStream.Free; 
     end; 
    finally 
     DestinationStream.Free; 
    end; 
    finally 
    SourceStream.Free; 
    end; 
end; 

내 문제는이 델파이 7의 경우 올바른 TXT 파일을 생성하지만, 델파이 XE4의 경우, 그것은 각각의 모든 문자 사이에 쓰레기 값을 도입한다는 것이다.

예 :

Delphi 7: abcdedfgh 
Delphi XE4: aNULbNULcNULdNULeNULfNULgNULhNUL 

NUL 모든 문자들 사이에 삽입된다. 나는 변화하는 선언을 시도했다

Buffer: array [0..1023] of Char; 

to Buffer: array [0..1023] of AnsiChar; 그러나 이것은 효과가 없었다.

+0

버퍼 대신 Char의 배열을 사용하는 것이 더 좋지만 여기서는 문제가되지 않습니다. XE4 텍스트는 유니 코드 인코딩 (UTF16?)과 같습니다. 라틴 심볼의 경우 항상 0 + ASCII 코드입니다. 같은 TXT 파일을 입력 (아마 코드에서 테스트 파일을 생성)하고 출력 (문자열 또는 다른 것으로 데이터를 읽는 것과 같은)에 다른 변환이없는 것이 확실합니까? –

+0

포팅 한 거대한 애플리케이션에서 코드를 직접 게시 한 것처럼 보입니다. SSCCE를 게시했다면 훨씬 쉬울 것입니다. 그렇게 해봤자 문제가 해결되었을 것입니다. 마르코의 종이 읽었 니? –

+0

@DavidHeffernan - 나는 이것을 나란히 읽고있다. –

답변

2

먼저 압축 해제 스트림 클래스가 무엇이든 올바르게 구현되었다고 가정합니다. 어떤 경우에는 질문의 코드가 실제로 괜찮습니다. 파일을 성공적으로 압축 해제합니다. 그것은 사용하는 버퍼의 두 배를 할당하기 때문에 조금 엉성합니다. 버퍼는 char가 아닌 byte 배열이어야합니다. 매직 1024 상수를 반복하지 말고 SizeOf (Buffer)를 사용하십시오. 그리고 Write 호출은 오류 검사를 추가하는 WriteBuffer가 더 좋습니다.

두 출력의 차이점은 단순히 하나는 8 비트 인코딩으로 인코딩되고 다른 하나는 16 비트 인코딩으로 인코딩된다는 것입니다. 아마도 UTF-16 일 것입니다.

의도적인지 여부는 말하기 어렵습니다. 압축 된 파일을 만든 프로세스를 살펴볼 필요가 있습니다. 예를 들어 압축 된 파일은 Delphi 문자열을 압축하여 생성됩니다. D7에서 문자열은 8 비트 인코딩이지만 DXE4에서는 16 비트 인코딩입니다.

명백한 단계는 두 입력 파일 인 D7과 DXE4 파일을 비교하는 것입니다. 당신은 그들이 동일하길 기대합니다. 그러나 그들은 그렇습니까?


다른 가능한 원인은 압축 풀기 스트림 클래스가 손상되었다는 것입니다. 그것은 좋은 것으로 알려진 ZLib 클래스처럼 보입니다.

+0

당신이 옳습니다. 압축 된 내 XML 파일이 잘못되었습니다. FCompressionStream.Write (strBuffer [1], Length (strBuffer))는 한 번에 한 라인 씩 받아들이고 압축합니다. 하지만 문자 길이가 유니 코드 델파이에서 두 번이라고 생각하기 때문에 문자열을 반으로 줄여서 Lenght (strBuffer) 문제를 관찰했습니다. 그래서 문제를 없애기 위해 2를 곱했습니다. 내 마지막 델파이 코드는 다음과 같습니다 : FCompressionStream.Write (strBuffer [1], Length (strBuffer) * 2) –

+3

코드는 FCompressionStream.Write (Pointer (strBuffer) ^, Length (strBuffer) * SizeOf (Char))' –

+0

다비드에게 감사드립니다. 그것은 작동합니다. –