Bug 11995 – std.File.ByLine strips trailing empty line
Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-01-25T12:34:33Z
Last change time
2020-03-21T03:56:40Z
Assigned to
No Owner
Creator
monarchdodra
Comments
Comment #0 by monarchdodra — 2014-01-25T12:34:33Z
//----
import std.stdio;
void main()
{
File("stuff0", "w").write("line 1\nline 2");
File("stuff1", "w").write("line 1\nline 2\n");
File("stuff2", "w").write("line 1\nline 2\na");
File("stuff3", "w").write("line 1\nline 2\n\n\n");
writeln(File("stuff0").byLine());
writeln(File("stuff1").byLine());
writeln(File("stuff2").byLine());
writeln(File("stuff3").byLine());
}
//----
["line 1", "line 2"]
["line 1", "line 2"]
["line 1", "line 2", "a"]
["line 1", "line 2", "", ""]
//----
The problem is that the last empty line is stripped away. This can be a problem for algorithms that copy/mutate files, as they can't reliably preserve the exact amount of lines to produce: File0 and File1 produced the exact same output, but are different :/
I think the correct output should be:
//----
["line 1", "line 2"]
["line 1", "line 2", ""]
["line 1", "line 2", "a"]
["line 1", "line 2", "", "", ""]
//----
With this scheme, it's simple: every line in the file gets an entry, and the last line of byLine does not actually have a terminator.
This means that something like:
File("out.txt", "w").writefln("%(%s\n%)", File("in.txt").byLine());
Will *exactly* duplicate the input file.
Comment #1 by peter.alexander.au — 2014-01-25T16:07:40Z
I agree, but I wonder if this is too much of a breaking change? I imagine byLine is used a lot, and I could easily see use cases that would break on this change.
Comment #2 by andrej.mitrovich — 2014-01-26T04:09:27Z
I don't think this is a bug. The "standard" line has a trailing newline, you even get warned about it missing for the last line by various programs.
If you want to exactly reproduce the original text use KeepTerminator.yes. This also works for mixed line endings on Windows (CRLF and LF).
Comment #5 by b2.temp — 2015-11-27T16:32:34Z
No, you forgot that the \n is part of the line:
your file is filled with:
"line 1\nline 2\n\n\n"
you expect byLine to output:
["line 1", "line 2", "", "", ""]
but "line 1\nline 2\n\n\n" contains **four** lines, not five:
line1\n
line2\n
\n
\n