2009-09-16 19 views
13

ho Delphi codice 2007, che assomiglia a questo:Scrivi stringa in un TFileStream in Delphi 2010

procedure WriteString(Stream: TFileStream; var SourceBuffer: PChar; s: string); 
begin 
    StrPCopy(SourceBuffer,s); 
    Stream.Write(SourceBuffer[0], StrLen(SourceBuffer)); 
end; 

io lo chiamo così:

var 
    SourceBuffer : PChar; 
    MyFile: TFileStream; 

.... 

SourceBuffer := StrAlloc(1024); 
MyFile := TFileStream.Create('MyFile.txt',fmCreate); 
WriteString(MyFile,SourceBuffer,'Some Text'); 
.... 

Questo ha funzionato in Delphi 2007, ma mi dà un sacco di personaggi spazzatura in Delphi 2010. So che questo è dovuto a problemi di conformità unicode, ma non sono sicuro di come affrontare il problema.

Ecco quello che ho provato finora:

  • Modificare il tipo di dati di SourceBuffer (e anche il parametro atteso da WideString) per PWideChar

  • Ognuno dei suggestions listed here

Cosa sto sbagliando?

risposta

14

Non è necessario un buffer separato per scrivere una stringa in un flusso. Probabilmente il modo più semplice per farlo è quello di codificare la stringa da UTF8, in questo modo:

procedure TStreamEx.writeString(const data: string); 
var 
    len: cardinal; 
    oString: UTF8String; 
begin 
    oString := UTF8String(data); 
    len := length(oString); 
    self.WriteBuffer(len, 4); 
    if len > 0 then 
     self.WriteBuffer(oString[1], len); 
end; 

function TStreamEx.readString: string; 
var 
    len: integer; 
    iString: UTF8String; 
begin 
    self.readBuffer(len, 4); 
    if len > 0 then 
    begin 
     setLength(iString, len); 
     self.ReadBuffer(iString[1], len); 
     result := string(iString); 
    end; 
end; 

ho dichiarato TStreamEx come aiutante di classe per TStream, ma non dovrebbe essere troppo difficile da riscrivere questi come procedura e funzione da solo come il tuo esempio.

+1

Questo ha funzionato per me dopo ho rimosso il "self.WriteBuffer (len, 4);" - Sta scrivendo alcuni caratteri senza senso nel file di output. – JosephStyons

+4

Questi "caratteri incomprensibili" sono la lunghezza della stringa, quindi la funzione di lettura sa quanto è necessario rileggere. Se è necessario che sia testo normale, è necessario un altro modo per dire a readString dove fermarsi. –

+0

Sto scrivendo questo file per un'altra applicazione per leggerlo, quindi non è importante che io possa leggerlo di nuovo. – JosephStyons

12

Delphi 2010 è una bella soluzione per questo, qui documentata:

http://docwiki.embarcadero.com/CodeExamples/en/StreamStrRdWr_%28Delphi%29

var 
    Writer: TStreamWriter; 
... 

    { Create a new stream writer directly. } 
    Writer := TStreamWriter.Create('MyFile.txt', false, TEncoding.UTF8); 
    Writer.Write('Some Text'); 

    { Close and free the writer. } 
    Writer.Free(); 
+4

Il collegamento è interrotto. Assomiglia a questo: http://docwiki.embarcadero.com/CodeExamples/en/StreamStrRdWr_%28Delphi%29 – jonjbar

+1

John, grazie per la correzione al link. Sembra una violazione della regola d'oro per i siti Web - mai rompere un permalink. In particolare per un url banale rinominare come questo. –

Problemi correlati