Створіть .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 #.


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. Все-таки говорити неправильно трохи крайно, але можна сказати неефективно. Ми також не повинні забувати, що перевірка існування може використовуватися не лише для запису / доступу для читання, але може використовуватися й іншими питаннями, тому для нових початківців ця тема корисна для розуміння того, як вона працює. Однак якщо ви можете додати відповідь, включаючи всі визначені вами тут визначення та причину, чому краще, що допоможе чимало як відповідь і, ймовірно, буде обрано як правильне.
Berker Yüceer

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
заверніть i в користування (див. відповідь нижче).
Девід Тілен

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
Девін C

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!");
   }
}

У мене є та ж проблема, і я знаходжу цей плакат, але рішення тут не вирішують мою проблему. Тому я використовую деякі шматочки розчину і просто додаю Dispose (). Моя мета не передбачає копію-вставлення.
Ек

1
Я не пропоную це зробити; Я кажу, що, не враховуючи це у вашій відповіді, оригінальний плакат не дізнається, чому ви внесли внесені вами зміни або що вони повинні здійснити. Завжди включайте всю релевантну інформацію під час публікації, щоб люди знали все, що ви робите. :)
DiMono

1
Це працює, тому що не дає помилки, яка говорить про те, що ви не можете писати в новостворений файл, оскільки він використовується іншим процесом. Ключовим є .Dispose (). Дуже дякую!
GenXisT

Це жодним чином не вирішує питання, що стосується збереження існуючого вмісту.
Ben Voigt

Немає сенсу телефонувати 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");

Це саме те, що мені було потрібно, але як я можу зробити так, щоб новий вміст починався з нового рядка? Я використовую файли CSV.
NiallUK

Я думаю, що не існує простого рішення. Я б запропонував вам перевірити цю публікацію. stackoverflow.com/questions/1343044 / ...
R.Cha


3

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

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!");
    }
}

Redudant File.AppendText(path), і з ним не потрібно перевіряти File.Exists(path). І If (not A) Else If (A)це дивно If / Else. По суті, в цьому питанні немає нічого хорошого, немає коду пояснення, який є редумантом іншої відповіді.
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 метод (String, String)

.NET Framework (поточна версія) Інші версії

Відкриває файл, додає до нього вказаний рядок, а потім закриває файл. Якщо файл не існує, цей метод створює файл, записує вказаний рядок у файл, а потім закриває файл. Простір імен: Асамблея System.IO: mscorlib (в mscorlib.dll)

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

AppendAllText


1
using(var tw = new StreamWriter(path, File.Exists(path)))
{
    tw.WriteLine(message);
}

Як правило, відповіді набагато корисніші, якщо вони включають пояснення того, що призначений для виконання коду та чому це вирішує проблему, не вводячи інших.
Тім Дікманн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.