2014-09-29 4 views
1

Не нужно было публиковать здесь какое-то время, но у меня есть проблема с реализацией потоков. При написании строки в FileStream, то resultnig текстовый файл имеет лишние пробелы, вставленные между символамидополнительные пробелы с преобразованием типа строки в буфер, неявное в Filestream.WriteBuffer method

Так при выполнении этого метода:

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; 

(который является урезанная метод тестирования, писать только заголовки). Полученный CSV-файл для «OUTPUTFILE» читает

«measuredmoduletempera ры, и так далее, если смотреть в WordPad, но не в Excel, блокнот и т.д. Я предполагаю, сво SizeOf (Char) утверждение, которое является неправильным в unicode, но я не уверен, что будет правильным вставить здесь. «ExportLogfile», кажется, работает нормально, но не «OUTPUTFILE»

Из того, что я читал в другом месте этого написание в Юникоде, который является проблемой & не WordPad см 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

Любых предложения людей? большое спасибо, Брайан

ответ

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 класс. Поставляйте выходной поток (или имя файла) и кодирование при создании объекта. А затем позвоните Write или WriteLine, чтобы добавить текст.

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

Я предположил UTF-8 здесь, но вы можете легко указать другую кодировку.

+0

Дэвид, ясный и очень полезный ответ, как всегда, большое спасибо, Брайан – SolarBrian

 Смежные вопросы

  • Нет связанных вопросов^_^