Search code examples
delphidelphi-2010

Delphi 2010 WriteLn to TextFile cutting off around 55 characters


Given this mess (designed years ago to write some data out csv "field1","field2") the output file has began stopping around 55 characters. Same happens in a showmessage() call or placing inside a local String variable. Converting to a TStringList to clean the code up even fails in the same way. Inspecting this as a local string variable in the IDE while the code is stopped shows the entire built string as planned. ShowMessage() even puts trailing ellipsis ... on the end.

I end up with "LD","BC63781S","JACKSON","MS","DENVER","CO","1186","0"... in showmessage and "LD","BC63781S","JACKSON","MS","DENVER","CO","1186","0" in the on disk file.

Better readability https://gist.github.com/788839

Writeln(F,
  '"'+ ACtion
  + '","' + Ini.ReadString('IP_ITS','BAccount','TEST')
  + '","' + FieldByName('PICKCITY').AsString
  + '","' + FieldByName('PICKST').AsString
  + '","' + FieldByName('DROPCITY').AsString
  + '","' + FieldByName('DROPST').AsString
  + '","' + FieldByName('TOT_MILES').AsString
  + '","' + FloatToStr(AWeight)
  + '","' + FieldByName('LENGTH').AsString
  + '","' + FloatToStr(AStops)
  + '","' + ''{grosspay}
  + '","' + FieldByName('PICK_DATE').AsString
  + '","' + FieldByName('PICK_TIME').AsString
  + '","' + FieldByName('DROP_DATE').AsString
  + '","' + FieldByName('DROP_TIME').AsString
  + '","' + AEquip
  + '","","' + ALTL
  + '"' + ',"","' + '","1","'
  + Ini.ReadString('IP_ITS','BComp','BAccount')
  + FieldByName('PRO_NO').AsString
  + '","","","","",""'
  )

Solution

  • Two fix possitibilies:

    1) Instead of the + sign between each string, just use a , instead. It will let Writeln() do the text concatenation.

              Writeln(F, '"',ACtion,'","', Ini.ReadString('IP_ITS','BAccount','TEST'),'","',
                FieldByName('PICKCITY').AsString,'","',FieldByName('PICKST').AsString,'","',
                FieldByName('DROPCITY').AsString,'","',FieldByName('DROPST').AsString,'","',
                FieldByName('TOT_MILES').AsString,'","',FloatToStr(AWeight),","',
                FieldByName('LENGTH').AsString,'","',FloatToStr(AStops),
                '","',''{grosspay},'","',FieldByName('PICK_DATE').AsString,
                '","',FieldByName('PICK_TIME').AsString,'","',FieldByName('DROP_DATE').AsString,
                '","',FieldByName('DROP_TIME').AsString,'","',AEquip,
                '","","',ALTL,'"' , ',"","',
                '","1","',Ini.ReadString('IP_ITS','BComp','BAccount'),FieldByName('PRO_NO').AsString,
                '","","","","",""');
    

    2) Use a Format() then an open parameter array - this is my preferred way, because it will be also more easy to fix/maintain

      Writeln(F, format('"%s","%s","%s","%s","%s","%s","%s",  ....
        [ACtion,Ini.ReadString('IP_ITS','BAccount','TEST'),FieldByName('PICKCITY').AsString, ..... ]));
    

    And in all cases, make sure you've set a writing buffer of some size, and are using {$I-}:

    procedure TClassData.SaveToFile(const FileName: TFileName);
    var F: system.Text;
        buf: array[word] of byte;
    begin
      {$I-}
      assign(F,FileName);
      system.SetTextBuf(F,buf);
      rewrite(F);
      if ioresult=0 then
      begin
        writeln(F,...
        ...