Файл .NET.WriteAllLines оставляет пустую строку в конце файла

когда я сохраняю содержимое массива String[] с помощью System.ИО.Файл.WriteAllLines, в конце файла всегда остается пустая строка. Например:

System.IO.File.WriteAllLines(Application.dataPath + "/test.txt",["a", "b", "c"]);

создает файл (без подчеркивания):

a
b
c
_

здесь уже была такая тема: пустая строка в файле .Net.WriteAllLines, это ошибка?, но autor сказал, что "я думаю, что что-то не так с моими данными,это моя проблема, но не WritAllLines", и он был закрыт как " слишком локализованный" (?!?).

Это ошибка? Как я могу легко избавиться от него (пока я просто игнорирую его при повторном чтении файла)?

7 ответов


на WriteAllLines метод записать каждую строку в массиве с последующим разрывом строки. Это означает, что вы всегда будете получать эту "пустую строку" в своем файле.

точку зрения, высказанную в посте вы связаны, что при работе ReadAllLines который считает строку символами, завершенными разрывом строки. Поэтому, когда вы используете метод read в файле, который вы только что написали, вы должны получить те же самые строки.

Если Вы читаете файл по-другому, то вы придется иметь дело с разрывом строк себя.

по сути то, что вы видите-это ожидаемое поведение.


как указывали другие, именно так это и работает. Вот метод, который делает это без лишних строки:

public static class FileExt
{
    public static void WriteAllLinesBetter(string path, params string[] lines)
    {
        if (path == null)
            throw new ArgumentNullException("path");
        if (lines == null)
            throw new ArgumentNullException("lines");

        using (var stream = File.OpenWrite(path))
        using (StreamWriter writer = new StreamWriter(stream))
        {
            if (lines.Length > 0)
            {
                for (int i = 0; i < lines.Length - 1; i++)
                {
                    writer.WriteLine(lines[i]);
                }
                writer.Write(lines[lines.Length - 1]);
            }
        }
    }
}

использование:

FileExt.WriteAllLinesBetter("test.txt", "a", "b", "c");

пишет:

    aenter
    benter
    c

WriteAllLines записывает каждую запись в массиве и добавляет новую строку.
Как вы можете видеть, каждая строка находится на своей собственной строке, это означает, что ваша последняя запись заканчивается новой строкой, и вы видите еще одну строку в файле. Вы могли бы доказать это с hexdecimal дамп файл

просмотр исходного кода WriteAllLines подтверждает это.
Внутренне он использует textwriter в.WriteLine (строка) метод.


@Virtlink решение почти идеальный. На самом деле есть сценарий, где вы получите мусор в конце файла - когда файл существует, и его содержимое больше, чем новое содержимое. Перед записью нового содержимого файла просто сбросьте длину файла до нуля.

    public static void WriteAllLinesBetter(string path, params string[] lines)
    {
        if (path == null)
            throw new ArgumentNullException("path");
        if (lines == null)
            throw new ArgumentNullException("lines");

        using (var stream = File.OpenWrite(path))
        {
            stream.SetLength(0);
            using (var writer = new StreamWriter(stream))
            {
                if (lines.Length > 0)
                {
                    for (var i = 0; i < lines.Length - 1; i++)
                    {
                        writer.WriteLine(lines[i]);
                    }
                    writer.Write(lines[lines.Length - 1]);
                }
            }
        }
    }

Я сделал то же самое, просто добавив строку :3 , надеюсь, что помогает кто-то

    for(int i = 0; i < Length; i++)
    {
        line = getLocation(i).X.ToString("0.0", nfi) + ',' + getLocation(i).Y.ToString("0.000", nfi) + ',' + getColorRaw(i).R.ToString("0.000", nfi) + ',' + getColorRaw(i).G.ToString("0.000", nfi) + ',' + getColorRaw(i).B.ToString("0.000", nfi);
        writer.Write(line);
        if( i < Length - 1) writer.Write("\n");

чтобы избавиться от трейлинга новой строки, лучшим решением было бы, когда вы читаете его с .ReadAllLines() фактически отклонить последний элемент из вашего массива строк.


самый простой способ для меня сделать это был usning AppendAllText для последней строки:

if ($i -ne $lines.Count - 1){
     $newLines += $lines[$i]
    } else {
     $lastLine = $lines[$i]
}

[IO.File]::WriteAllLines($file.FullName, $newLines);
[IO.File]::AppendAllText($file.FullName, $lastLine);