1

暂时不需要在这里发帖,但我在实现文件流时遇到了问题。将字符串写入文件流时,结果文本文件在每个字符之间插入了额外的空格

所以在运行这个方法时:

Function TDBImportStructures.SaveIVDataToFile(const AMeasurementType: integer;
  IVDataRecordList: TIV; ExportFileName, LogFileName: String;
  var ProgressInfo: TProgressInfo): Boolean; // AM
var
  TempString: unicodestring;
  ExportLogfile, OutputFile: TFileStream;
begin
  ExportLogfile := TFileStream.Create(LogFileName, fmCreate);
  TempString :=
    'FileUploadTimestamp, Filename, MeasurementTimestamp, SerialNumber, DeviceID, PVInstallID,'
    + #13#10;
  ExportLogfile.WriteBuffer(TempString[1], Length(TempString) * SizeOf(Char));
  ExportLogfile.Free;

  OutputFile := TFileStream.Create(ExportFileName, fmCreate);
  TempString :=
    'measurementdatetime,closestfiveseconddatetime,closesttenminutedatetime,deviceid,'
    + 'measuredmoduletemperature,moduletemperature,isc,voc,ff,impp,vmpp,iscslope,vocslope,'
    + 'pvinstallid,numivpoints,errorcode' + #13#10;
  OutputFile.WriteBuffer(TempString[1], Length(TempString) * SizeOf(Char));
  OutputFile.Free;
end;

(这是一种精简的测试方法,只写标题)。'OutPutFile' 生成的 csv 文件读取

'measuredmoduletempera ture 等在写字板中查看时,而不是在 excel、记事本等中查看。我猜它的 SizeOf(Char) 语句在 unicode 上下文中是错误的,但我不确定什么是正确的在此处插入。'ExportLogfile' 似乎工作正常,但不是 'OutPutFile'

从我在其他地方读到的内容来看,问题是用 unicode 书写,而不是写字板,请参阅http://social.msdn.microsoft.com/Forums/en-US/7e040fd1-f399-4fb1-b700-9e7cc6117cc4/ unicode-to-files-and-console-vs-notepad-wordpad-word-etc?forum=vcgeneral

各位有什么建议吗?非常感谢,布赖恩

4

1 回答 1

3

您正在编写 16 位 UTF-16 编码字符。然后将文本视为 ANSI 编码文本。这种不匹配解释了这种行为。实际上,您没有多余的空格,它们是零字节,被解释为空字符。

您需要决定要使用哪种编码。哪些程序会读取文件?他们期待哪种文本编码?读取 csv 文件的程序很少能理解 UTF-16。

一个快速的解决方法是切换到使用AnsiString这将导致 8 位文本。但不支持国际文本。需要支持国际文本吗?那么也许你需要UTF-8。同样,您可以使用 执行快速修复Utf8String,但我认为您应该更深入地研究。

将文本处理为二进制转换很奇怪。使用起来会简单得多TStringList,调用Add添加行,然后在保存文件时指定编码。

List.Add(...);
List.Add(...);
// etc. 
List.SaveToFile(FileName, TEncoding.UTF8);

一种可能更优雅的方法是使用TStreamWriter该类。创建对象时提供输出流(或文件名)和编码。然后调用WriteWriteLine添加文本。

Writer := TStreamWriter.Create(FileName, TEncoding.UTF8);
try
  Writer.WriteLine(...);
  // etc. 
finally
  Writer.Free;
end;

我在这里假设为 UTF-8,但您可以轻松指定不同的编码。

于 2014-09-29T17:12:14.597 回答