Tengo un archivo .\input.txtcomo este:
aaa
bbb
ccc
Si lo leo usando TStrings.LoadFromFiley lo escribo de nuevo (incluso sin aplicar ningún cambio) TStrings.SaveToFile, crea una línea vacía al final del archivo de salida.
var
Lines : TStrings;
begin
Lines := TStringList.Create;
try
Lines.LoadFromFile('.\input.txt');
//...
Lines.SaveToFile('.\output.txt');
finally
Lines.Free;
end;
end;
Se puede observar el mismo comportamiento utilizando la TStrings.Textpropiedad que devolverá una cadena que contiene una línea vacía al final.
delphi
tstringlist
Fabrizio
fuente
fuente

\ncarácter y la función agrega\nel archivo? ¿O la función agrega literalmente un\nderecho después de uno existente\nal final del archivo? POSIX requiere que los archivos de texto tengan todas sus líneas terminadas por un\n, solo para su información. Un montón de software fue escrito para seguir algunas normas y por eso una gran cantidad de editores añadirá la terminación falta\nal guardar archivos por defecto (por ejemplovim, entornos de desarrollo, etc., todo de forma predeterminada hacer que sus archivos compatible con POSIX.)Respuestas:
Para Delphi 10.1 y posteriores hay una propiedad que
TrailingLineBreakcontrola este comportamiento.fuente
TrailingLineBreakpropiedad tan pronto como actualice el IDE. +1 y aceptadoPara Delphi 10.1 (Berlín) o posterior, la mejor solución se describe en la respuesta de Uwe.
Para versiones anteriores de Delphi, encontré una solución creando una clase secundaria
TStringListy anulando laTStrings.GetTextStrfunción virtual, pero me alegrará saber si hay una mejor solución o si alguien más encontró algo incorrecto en mi soluciónInterfaz:
Implementación:
Ejemplo:
fuente
SetLength(Result, -2).GetTextStr, siLength(Result)es0, entonces lo hacesSetLength(Result, -2), lo cual es malo. Podría ser el caso de que el efecto sea el mismoSetLength(Result, 0), pero no tengo ninguna garantía al respecto. La documentación oficial, al menos, no contiene dicha garantía. (Entonces, en teoría, podrían suceder cosas malas)Length(Result) = 1, entonces lo hacesSetLength(Result, -1), ¡lo cual es igualmente malo! Además, podría ser el caso queResultno termine con un salto de línea, en cuyo caso eliminará los dos últimos caracteres de la última línea. Eso también es un error. (Y eso podría suceder, por ejemplo, si lo usaTrailingLineBreak, sospecho. Incluso si no, puede haber otras instancias). Realmente debería probar si la cadena realmente termina con un salto de línea, comoif not IncludeLastLineBreakInText and Result.EndsWith(LineBreak) then.Pos(LineBreak, Result) = Length(Result) - Length(LineBreak) + 1.PosDa el índice de la primera coincidencia. Si su cadena contiene 6 saltos de línea, le dará la posición de la primera, pero claramente espera la última one ...