2016-02-29 8 views
8

मेरे पास एक यूरेकालॉग बग रिपोर्ट है जो EEncodingError दिखाती है। लॉग TFile.AppendAllText पर इंगित करता है। मैं फोन TFile.AppendAllText मेरा यह प्रक्रिया है:क्या कारण हो सकता है "लक्ष्य मल्टी-बाइट कोड पृष्ठ में यूनिकोड वर्ण के लिए कोई मैपिंग मौजूद नहीं है"?

procedure WriteToFile(CONST FileName: string; CONST uString: string; CONST WriteOp: WriteOpperation; ForceFolder: Boolean= FALSE);  // Works with UNC paths 
begin 
if NOT ForceFolder 
OR (ForceFolder AND ForceDirectoriesMsg(ExtractFilePath(FileName))) then 
    if WriteOp= (woOverwrite) 
    then IOUtils.TFile.WriteAllText (FileName, uString) 
    else IOUtils.TFile.AppendAllText(FileName, uString); 
end; 

यह EurekaLog से जानकारी है।

enter image description here

enter image description here

क्या ऐसा हो सकता है?

{$APPTYPE CONSOLE} 

uses 
    System.SysUtils, System.IOUtils; 

var 
    FileName: string; 

begin 
    try 
    FileName := TPath.GetTempFileName; 
    TFile.WriteAllText(FileName, 'é', TEncoding.ANSI); 
    TFile.AppendAllText(FileName, 'é'); 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
end. 

यहाँ मैं एएनएसआई के रूप में मूल फ़ाइल में लिखा है:

उत्तर

11

इस कार्यक्रम त्रुटि है कि आप रिपोर्ट reproduces। और फिर AppendAllText कहा जाता है जो यूटीएफ -8 के रूप में लिखने की कोशिश करेगा। क्या होता है कि हम इस समारोह में समाप्त होता है: इस लाइन से

class procedure TFile.AppendAllText(const Path, Contents: string); 
var 
    LFileStream: TFileStream; 
    LFileEncoding: TEncoding; // encoding of the file 
    Buff: TBytes; 
    Preamble: TBytes; 
    UTFStr: TBytes; 
    UTF8Str: TBytes; 
begin 
    CheckAppendAllTextParameters(Path, nil, False); 

    LFileStream := nil; 
    try 
    try 
     LFileStream := DoCreateOpenFile(Path); 
     // detect the file encoding 
     LFileEncoding := GetEncoding(LFileStream); 

     // file is written is ASCII (default ANSI code page) 
     if LFileEncoding = TEncoding.ANSI then 
     begin 
     // Contents can be represented as ASCII; 
     // append the contents in ASCII 

     UTFStr := TEncoding.ANSI.GetBytes(Contents); 
     UTF8Str := TEncoding.UTF8.GetBytes(Contents); 

     if TEncoding.UTF8.GetString(UTFStr) = TEncoding.UTF8.GetString(UTF8Str) then 
     begin 
      LFileStream.Seek(0, TSeekOrigin.soEnd); 
      Buff := TEncoding.ANSI.GetBytes(Contents); 
     end 
     // Contents can be represented only in UTF-8; 
     // convert file and Contents encodings to UTF-8 
     else 
     begin 
      // convert file contents to UTF-8 
      LFileStream.Seek(0, TSeekOrigin.soBeginning); 
      SetLength(Buff, LFileStream.Size); 
      LFileStream.ReadBuffer(Buff, Length(Buff)); 
      Buff := TEncoding.Convert(LFileEncoding, TEncoding.UTF8, Buff); 

      // prepare the stream to rewrite the converted file contents 
      LFileStream.Size := Length(Buff); 
      LFileStream.Seek(0, TSeekOrigin.soBeginning); 
      Preamble := TEncoding.UTF8.GetPreamble; 
      LFileStream.WriteBuffer(Preamble, Length(Preamble)); 
      LFileStream.WriteBuffer(Buff, Length(Buff)); 

      // convert Contents in UTF-8 
      Buff := TEncoding.UTF8.GetBytes(Contents); 
     end; 
     end 
     // file is written either in UTF-8 or Unicode (BE or LE); 
     // append Contents encoded in UTF-8 to the file 
     else 
     begin 
     LFileStream.Seek(0, TSeekOrigin.soEnd); 
     Buff := TEncoding.UTF8.GetBytes(Contents); 
     end; 

     // write Contents to the stream 
     LFileStream.WriteBuffer(Buff, Length(Buff)); 
    except 
     on E: EFileStreamError do 
     raise EInOutError.Create(E.Message); 
    end; 
    finally 
    LFileStream.Free; 
    end; 
end; 

त्रुटि उपजा:

if TEncoding.UTF8.GetString(UTFStr) = TEncoding.UTF8.GetString(UTF8Str) then 

समस्या यह है कि UTFStr तथ्य मान्य UTF-8 में नहीं है। और इसलिए TEncoding.UTF8.GetString(UTFStr) एक अपवाद फेंकता है।

यह TFile.AppendAllBytes में एक दोष है। यह देखते हुए कि यह पूरी तरह से अच्छी तरह से जानता है कि UTFStrANSI एन्कोडेड है, TEncoding.UTF8.GetString पर कॉल करने के लिए इसका कोई मतलब नहीं है।

आपको इस दोष के लिए एम्बरकाडेरो को एक बग रिपोर्ट सबमिट करनी चाहिए जो अभी भी डेल्फी 10 सिएटल में मौजूद है। इस बीच आपको TFile.AppendAllBytes का उपयोग नहीं करना चाहिए।

+0

टीस्ट्रीम रीडर के बारे में क्या? एक सभ्य विकल्प लगता है और यह IOUtils पर आधारित नहीं है। – Ampere

+0

पेर्फ थोड़ा सा डोडी है। मैं फ़ाइल के जीवनकाल के ज्ञान के बिना सलाह देना नहीं चाहता हूं और कौन इसे संशोधित करता है। –

संबंधित मुद्दे