สร้างไฟล์. 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 ฉันเห็นด้วยอย่างยิ่งว่าคุณควรเขียนคำตอบทั้งหมดเพื่ออธิบายให้ชัดเจน ความคิดเห็นไม่ใช่เพื่อการตอบรับและฉันอยากรู้อยากเห็นอย่างจริงใจเกี่ยวกับสภาพการแข่งขันเหล่านี้และวิธีที่คุณเสนอให้แก้ไข
Matthieu Foltzer

คำตอบ:


167

ใช้ตัวสร้างที่ถูกต้อง :

else if (File.Exists(path))
{
    using(var tw = new StreamWriter(path, true))
    {
        tw.WriteLine("The next line!");
    }
}

11
คำตอบแรกคำตอบที่ง่ายที่สุดคำตอบที่มีประโยชน์ที่สุดสำหรับฉัน lol เมื่อฉันดูมันฉันก็เหมือน: ฮะ? เพียงแค่เพิ่ม "จริง" ก็เพียงพอแล้ว? ทำไมฉันไม่เห็นสิ่งนั้นมาก่อน ประณาม ... ฉันรู้สึกเหมือนขอบคุณโง่ทั้งหมด ฉันคิดคำตอบที่ดีเหล่านี้ล่วงหน้า
Berker Yüceer

7
คำใบ้: หากไม่มีไฟล์ตัวสร้างนี้จะสร้างไฟล์ใหม่
Abou-Emish

1
ห่อฉันด้วยการใช้ (ดูคำตอบด้านล่าง)
David Thielen

1
การปิดซ้ำซ้อนหากคุณใช้
Michael Freidgeim

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
Devin 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 () เป้าหมายของฉันไม่เกี่ยวข้องกับ copy-paste
Aek

1
ฉันไม่แนะนำให้ทำ ฉันกำลังบอกว่าหากไม่มีการรวมไว้ในคำตอบของคุณโปสเตอร์ต้นฉบับจะไม่รู้ว่าทำไมคุณทำการเปลี่ยนแปลงที่คุณทำหรือสิ่งที่พวกเขาควรจะทำสำเร็จ รวมข้อมูลที่เกี่ยวข้องทั้งหมดไว้เสมอเมื่อคุณโพสต์เพื่อให้คนอื่นรู้ว่าคุณกำลังทำอะไรอยู่ :)
DiMono

1
วิธีนี้ใช้งานได้เนื่องจากไม่มีข้อผิดพลาดที่แจ้งว่าคุณไม่สามารถเขียนไปยังไฟล์ที่สร้างขึ้นใหม่เนื่องจากกระบวนการอื่นกำลังถูกใช้ .Dispose () คือกุญแจ ขอบคุณมาก!
GenXisT

สิ่งนี้ไม่ได้ตอบคำถาม แต่อย่างใดซึ่งเกี่ยวกับการรักษาเนื้อหาที่มีอยู่
Ben Voigt

ไม่มีจุดในการโทรClose()จากusingคำสั่งเนื่องจากทรัพยากรทั้งหมดจะถูกปิดก่อนที่จะถูกกำจัดโดยอัตโนมัติ
Sheridan

21

คุณไม่จำเป็นต้องตรวจสอบว่าไฟล์นั้นมีอยู่จริงหรือไม่เพราะ StreamWriter จะทำเพื่อคุณ หากคุณเปิดในโหมดต่อท้ายไฟล์จะถูกสร้างขึ้นหากไม่มีอยู่คุณจะผนวกและไม่เขียนทับ ดังนั้นการตรวจสอบครั้งแรกของคุณจึงซ้ำซ้อน

TextWriter tw = new StreamWriter(path, true);
tw.WriteLine("The next line!");
tw.Close(); 

1
ฉันพยายามหาตรรกะของคำตอบที่ยอมรับฉันรู้ว่าฉันเคยทำสิ่งนี้ในหนึ่งบรรทัดมาก่อน แต่ไม่สามารถจำไวยากรณ์ที่แน่นอนได้ ขอบคุณ.
Morvael

14

File.AppendAllText เพิ่มสตริงลงในไฟล์ นอกจากนี้ยังสร้างไฟล์ข้อความหากไม่มีไฟล์อยู่ หากคุณไม่จำเป็นต้องอ่านเนื้อหามันมีประสิทธิภาพมาก กรณีการใช้งานเป็นการบันทึก

File.AppendAllText("C:\\log.txt", "hello world\n");

นี่เป็นสิ่งที่ฉันต้องการ แต่ฉันจะทำให้เนื้อหาใหม่เริ่มต้นในบรรทัดใหม่ได้อย่างไร ฉันกำลังใช้ไฟล์ 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 ข้อความจะแทนที่ข้อความเดิม คุณสามารถใช้ผนวกคุณสมบัติเช่น:

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
หากคุณมีบล็อค 'use' อยู่ w.Close จะมีข้อมูลซ้ำซ้อน การกำจัดในตอนท้ายของการใช้บล็อกก็ทำเช่นเดียวกัน
Michael Freidgeim

-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 Method (String, String)

.NET Framework (รุ่นปัจจุบัน) รุ่นอื่น ๆ

เปิดไฟล์ต่อท้ายสตริงที่ระบุให้กับไฟล์จากนั้นปิดไฟล์ หากไฟล์ไม่มีอยู่วิธีนี้จะสร้างไฟล์เขียนสตริงที่ระบุไปยังไฟล์จากนั้นปิดไฟล์ Namespace: System.IO Assembly: mscorlib (ใน mscorlib.dll)

ไวยากรณ์ C # C ++ F # VB โมฆะแบบคงที่สาธารณะ AppendAllText (เส้นทางสตริงเนื้อหาสตริง) พา ธ พารามิเตอร์ประเภท: System.String ไฟล์ที่จะผนวกสตริงที่ระบุ content Type: System.String สตริงที่จะผนวกเข้ากับไฟล์

AppendAllText


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

โดยทั่วไปแล้วคำตอบมีประโยชน์มากขึ้นหากพวกเขามีคำอธิบายว่ารหัสนี้มีจุดประสงค์เพื่ออะไรและเหตุใดจึงแก้ปัญหาได้โดยไม่ต้องแนะนำผู้อื่น
Tim Diekmann
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.