Создайте файл .txt, если он не существует, и если он добавляет новую строку

161

Я хотел бы создать файл .txt и записать в него, и если файл уже существует, я просто хочу добавить еще несколько строк:

string path = @"E:\AppServ\Example.txt";
if (!File.Exists(path))
{
    File.Create(path);
    TextWriter tw = new StreamWriter(path);
    tw.WriteLine("The very first line!");
    tw.Close();
}
else if (File.Exists(path))
{
    TextWriter tw = new StreamWriter(path);
    tw.WriteLine("The next line!");
    tw.Close(); 
}

Но первая строка, кажется, всегда перезаписывается ... как я могу избежать записи в одной строке (я использую это в цикле)?

Я знаю, что это довольно простая вещь, но я никогда не использовал этот WriteLineметод раньше. Я совершенно новичок в C #.

Berker Yüceer
источник
3
Помните, что почти все ответы здесь неверны и зависят от условий гонки . Помните: шаблон if (file exists) { open file }почти всегда неверен во всех языках программирования! Для .NET решение заключается в использовании File.Open(path, FileMode.Append, FileAccess.ReadWrite)с соответствующими флагами.
ComFreek
«Значение FileMode, которое указывает, создается ли файл, если он не существует, и определяет, сохраняется ли содержимое существующих файлов или перезаписывается». то же самое делает .net вместо ручного подхода. Так что здесь все не так, это тот же процесс, который выполняется вручную. Вы можете сказать, что неэффективно, но неправильно сказать не считается.
Berker Yüceer
Разница в том, что File.Openвнутренне делегирует функцию WinAPI (см. Следующий комментарий), надеясь предотвратить состояние гонки. Большинство решений здесь не делают этого и, очевидно, зависят от условий гонки.
ComFreek
1
Проверка существования, однако, определяется FileMode.Append здесь .. и она направляет на проверку существования, а затем создает файл с CreateFileA. Все еще говорите что-то неправильно, но вы можете сказать, что это неэффективно. Мы также не должны забывать, что проверка существования не может использоваться только для доступа на запись / чтение, а также может использоваться другими вопросами, поэтому для начинающих эта тема полезна для понимания того, как она работает. Однако, если вы можете добавить ответ, включающий все определения, которые вы здесь написали, и причину, почему это лучше, это очень поможет в качестве ответа и, вероятно, будет выбрано как правильный.
Беркер Юсьер
1
@ComFreek Я полностью согласен, что вы должны написать полный ответ об этом, чтобы объяснить это ясно. Комментарии не для ответа, и мне искренне любопытно об этих условиях гонки и как вы предлагаете решить это.
Матье Фольцер,

Ответы:

167

Используйте правильный конструктор :

else if (File.Exists(path))
{
    using(var tw = new StreamWriter(path, true))
    {
        tw.WriteLine("The next line!");
    }
}
Дэниэл Хилгарт
источник
11
Первый ответ, Самый простой ответ, Самый полезный ответ для меня, лол. Когда я смотрел на это, я был похож: А? достаточно просто добавить «правда»? Почему я не вижу этого раньше? Черт ... Я чувствовал себя совершенно глупо, спасибо. Я действительно ценю эти добрые ответы.
Berker Yüceer
7
подсказка: если файл не существует, этот конструктор создает новый файл.
Абу-Эмиш
1
заверните меня в использование (см. ответ ниже).
Дэвид Тилен
1
Закрыть излишне, если вы используете
Майкл Фрейдгейм
2
-1 Это зависит от условий гонки и может привести к неправильному поведению! Возможно, лучше использовать File.Open(path, FileMode.Append, FileAccess.ReadWrite)и проверить размер файла через этот возвращаемый поток.
ComFreek
57
string path = @"E:\AppServ\Example.txt";
File.AppendAllLines(path, new [] { "The very first line!" });

Смотрите также File.AppendAllText (). AppendAllLines добавит новую строку в каждую строку без необходимости помещать ее туда самостоятельно.

Оба метода создадут файл, если он не существует, поэтому вам не нужно.

ГИЦЗ
источник
3
Я думаю, что это больше подходит для того, что пользователь спрашивал. Похоже, есть 2 проблемы. 1 - текст перезаписан - это потому, что WriteLine перезаписывает файл. В этом случае File.AppendAllText является более подходящим. и 2) - вопрос, как я могу создать свой файл и узнать, что я к нему добавляю. Хорошо знать, что File.AppendAllText создает файл, это был мой вопрос. StreamWriter не всегда подходит, это зависит от того, для чего используется это приложение. В любом случае это помогло мне. +1
Девин С
42
string path=@"E:\AppServ\Example.txt";

if(!File.Exists(path))
{
   File.Create(path).Dispose();

   using( TextWriter tw = new StreamWriter(path))
   {
      tw.WriteLine("The very first line!");
   }

}    
else if (File.Exists(path))
{
   using(TextWriter tw = new StreamWriter(path))
   {
      tw.WriteLine("The next line!");
   }
}
Aek
источник
У меня тоже такая же проблема, и я нахожу этот плакат, но решения здесь не решают мою проблему. Поэтому я использую некоторые решения и просто добавляю Dispose (). Моя цель - не копировать-вставить.
Aek
1
Я не предполагаю, что это сделал; Я говорю, что без включения этого в ваш ответ, оригинальный постер не будет знать, почему вы внесли изменения, которые вы сделали, или что они должны были выполнить. При публикации всегда включайте всю необходимую информацию, чтобы люди знали все о том, что вы делаете. :)
DiMono
1
Это работает, потому что это не выдает ошибку, которая говорит, что вы не можете записать во вновь созданный файл, потому что он используется другим процессом. .Dispose () является ключевым. Спасибо вам большое!
GenXisT
Это никоим образом не решает вопрос о сохранении существующего содержимого.
Бен Фойгт
Там нет смысла в вызове Close()из usingзаявления, так как все ресурсы будут закрыты перед удалением автоматически.
Шеридан
21

На самом деле вам не нужно проверять, существует ли файл, так как StreamWriter сделает это за вас. Если вы откроете его в режиме добавления, файл будет создан, если он не существует, тогда вы всегда будете добавлять и никогда не перезаписывать. Таким образом, ваша первоначальная проверка избыточна.

TextWriter tw = new StreamWriter(path, true);
tw.WriteLine("The next line!");
tw.Close(); 
Джон Болинг
источник
1
Я пытался выработать логику принятого ответа, я знал, что делал это в одну строку раньше, но не мог вспомнить точный синтаксис. Спасибо.
Морваэль
14

File.AppendAllText добавляет строку в файл. Он также создает текстовый файл, если файл не существует. Если вам не нужно читать контент, это очень эффективно. Вариант использования - регистрация.

File.AppendAllText("C:\\log.txt", "hello world\n");
R.Cha
источник
Это как раз то, что мне нужно, но как я могу сделать так, чтобы новый контент начинался с новой строки? Я использую файлы CSV.
NiallUK
Я думаю, что нет простого решения. Я бы посоветовал вам проверить эту публикацию. stackoverflow.com/questions/1343044/…
R.Cha
6

Вы просто хотите открыть файл в режиме «добавления».

http://msdn.microsoft.com/en-us/library/3zc0w663.aspx

Эд Мане
источник
да, это тоже полезно, но я искал быстрое и простое решение, и благодаря @Daniel Hilgarth он предоставил такое решение. так +1.
Berker Yüceer
3

Когда вы запускаете StreamWriter, он переопределяет текст, который был там раньше. Вы можете использовать свойство append следующим образом:

TextWriter t = new StreamWriter(path, true);
Матан Шахар
источник
3
 else if (File.Exists(path)) 
{ 
  using (StreamWriter w = File.AppendText(path))
        {
            w.WriteLine("The next line!"); 
            w.Close();
        }
 } 
Хлопать
источник
1
Если у вас есть блок «using», то w.Close является избыточным. Утилизация в конце использования блока делает то же самое.
Майкл Фрейдгейм
-1 Это зависит от условий гонки и может привести к неправильному поведению! Возможно, лучше использовать File.Open(path, FileMode.Append, FileAccess.ReadWrite)и проверить размер файла через этот возвращаемый поток.
ComFreek
2

Попробуй это.

string path = @"E:\AppServ\Example.txt";
if (!File.Exists(path))
{
    using (var txtFile = File.AppendText(path))
    {
        txtFile.WriteLine("The very first line!");
    }
}
else if (File.Exists(path))
{     
    using (var txtFile = File.AppendText(path))
    {
        txtFile.WriteLine("The next line!");
    }
}
Асири Джаявира
источник
Редудант File.AppendText(path), а с ним проверять не надо File.Exists(path). И If (not A) Else If (A)это странно, если / иначе. По сути, в этом вопросе нет ничего хорошего, нет объяснительного кода, который является избыточной версией другого ответа.
xdtTransform
-1 Это зависит от условий гонки и может привести к неправильному поведению! Возможно, лучше использовать File.Open(path, FileMode.Append, FileAccess.ReadWrite)и проверить размер файла через этот возвращаемый поток.
ComFreek
2

Вы можете просто использовать метод File.AppendAllText (), чтобы решить вашу проблему. Этот метод позаботится о создании файла, если он недоступен, об открытии и закрытии файла.

var outputPath = @"E:\Example.txt";
var data = "Example Data";
File.AppendAllText(outputPath, data);
Виджей Шаарук
источник
1

Из документации Microsoft вы можете создать файл, если он не существует, и добавить его в один вызов File.AppendAllText Method (String, String)

.NET Framework (текущая версия) Другие версии

Открывает файл, добавляет указанную строку в файл, а затем закрывает файл. Если файл не существует, этот метод создает файл, записывает указанную строку в файл, а затем закрывает файл. Пространство имен: System.IO Сборка: mscorlib (в mscorlib.dll)

Синтаксис C # C ++ F # VB public static void AppendAllText (путь строки, содержимое строки) Параметры path Тип: System.String Файл, к которому добавляется указанная строка. Содержание Тип: System.String Строка, добавляемая в файл.

AppendAllText

Дэвид Фози
источник
1
using(var tw = new StreamWriter(path, File.Exists(path)))
{
    tw.WriteLine(message);
}
Андреас Гусаков
источник
Как правило, ответы гораздо полезнее, если они включают в себя объяснение того, для чего предназначен код, и почему это решает проблему, не представляя других.
Тим Дикманн