Tạo một tệp .txt nếu không tồn tại và nếu nó nối thêm một dòng mới


161

Tôi muốn tạo một tệp .txt và ghi vào nó, và nếu tệp đã tồn tại, tôi chỉ muốn nối thêm một số dòng:

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(); 
}

Nhưng dòng đầu tiên dường như luôn bị ghi đè ... làm thế nào tôi có thể tránh viết trên cùng một dòng (tôi đang sử dụng dòng này trong một vòng lặp)?

Tôi biết đó là một điều khá đơn giản, nhưng tôi chưa bao giờ sử dụng WriteLinephương pháp này trước đây. Tôi hoàn toàn mới với C #.


3
Coi chừng rằng hầu hết tất cả các câu trả lời ở đây đều sai và tuân theo các điều kiện chủng tộc . Hãy nhớ rằng: mô hình if (file exists) { open file }hầu như luôn luôn sai trong tất cả các ngôn ngữ lập trình! Đối với .NET, giải pháp là sử dụng File.Open(path, FileMode.Append, FileAccess.ReadWrite)các cờ thích hợp.
ComFalet

"Giá trị FileMode chỉ định xem một tệp có được tạo nếu không tồn tại hay không và xác định xem nội dung của các tệp hiện có được giữ lại hay ghi đè." Vì vậy, điều tương tự được thực hiện bởi .net thay vì cách tiếp cận thủ công ở đây. Vì vậy, nó không sai ở đây, đó là quá trình tương tự được thực hiện thủ công. Bạn có thể nói không hiệu quả nhưng nói sai không tính.
Berker Yüceer

Sự khác biệt là: File.Opencác đại biểu nội bộ cho một chức năng WinAPI (xem bình luận tiếp theo) hy vọng ngăn chặn điều kiện cuộc đua. Hầu hết các giải pháp ở đây không làm điều này và rõ ràng là tùy thuộc vào điều kiện chủng tộc.
ComFalet

1
Tuy nhiên, kiểm tra sự tồn tại được xác định bởi FileMode. Hãy thêm vào đây .. và nó hướng đến một kiểm tra tồn tại sau đó tạo tệp với CreatFileA. Vẫn nói sai một chút cực đoan, nhưng bạn có thể nói không hiệu quả. Chúng ta cũng không nên quên kiểm tra sự tồn tại có thể không chỉ được sử dụng cho truy cập ghi / đọc cũng có thể được sử dụng bởi các vấn đề khác vì vậy đối với người mới bắt đầu, chủ đề này rất hữu ích để hiểu cách thức hoạt động của nó. Tuy nhiên nếu bạn có thể thêm một câu trả lời bao gồm tất cả các định nghĩa bạn đã viết ở đây và lý do tại sao nó tốt hơn sẽ giúp ích rất nhiều cho câu trả lời và có thể sẽ được chọn là chính xác.
Berker Yüceer

1
@ComFalet Tôi hoàn toàn đồng ý rằng bạn nên viết một câu trả lời đầy đủ về nó để giải thích rõ ràng. Nhận xét không phải để trả lời, và tôi thực sự tò mò về những điều kiện cuộc đua này và cách bạn đề xuất để giải quyết nó.
Matthieu Foltzer

Câu trả lời:


167

Sử dụng đúng hàm tạo :

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

11
Câu trả lời đầu tiên, Câu trả lời đơn giản nhất, Câu trả lời hữu ích nhất cho tôi lol. Khi tôi nhìn vào nó, tôi giống như: Hả? chỉ cần thêm ", đúng" là đủ? Tại sao tôi không thấy điều đó trước đây? Chết tiệt ... tôi cảm thấy như một lời cảm ơn hoàn toàn ngu ngốc. Tôi thực sự đi trước những câu trả lời tốt.
Berker Yüceer

7
gợi ý: Nếu tệp không tồn tại, hàm tạo này tạo một tệp mới.
Abou-Emish

1
bọc i trong một sử dụng (xem câu trả lời dưới đây).
David Thielen

1
Đóng là dư thừa, nếu bạn đã sử dụng
Michael Freidgeim

2
-1 Điều này tùy thuộc vào điều kiện chủng tộc và có thể tạo ra hành vi sai! Có lẽ nên sử dụng File.Open(path, FileMode.Append, FileAccess.ReadWrite)và kiểm tra kích thước tệp thông qua luồng trả về đó.
ComFalet

57
string path = @"E:\AppServ\Example.txt";
File.AppendAllLines(path, new [] { "The very first line!" });

Xem thêm File.Append ALLText (). AppendAllLines sẽ thêm một dòng mới vào mỗi dòng mà không cần phải tự đặt nó ở đó.

Cả hai phương pháp sẽ tạo tệp nếu nó không tồn tại để bạn không phải làm vậy.


3
Tôi nghĩ rằng điều này là phù hợp hơn cho những gì người dùng đã yêu cầu. Có vẻ như có 2 vấn đề. 1 là văn bản bị ghi đè - điều này là do WriteLine ghi đè lên tệp. Trong trường hợp này, File.AppendAllText phù hợp hơn. và 2) - câu hỏi làm thế nào tôi có thể tạo tệp của mình và biết tôi đang nối thêm vào đó. Thật tốt khi biết nó File.AppendAllText tạo tệp, đó là câu hỏi của tôi. StreamWriter không phải lúc nào cũng phù hợp, nó phụ thuộc vào ứng dụng đó được sử dụng để làm gì. Hoặc là trường hợp này đã giúp tôi ra ngoài. +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!");
   }
}

Tôi cũng có một vấn đề tương tự, và tìm thấy poster này nhưng các giải pháp ở đây không giải quyết được vấn đề của tôi. Vì vậy, tôi sử dụng một số phần của giải pháp và chỉ cần thêm Dispose (). Mục đích của tôi không liên quan đến sao chép-dán.
Aek

1
Tôi không cho rằng nó đã làm; Tôi đang nói rằng không bao gồm điều đó trong câu trả lời của bạn, người đăng ban đầu sẽ không biết lý do tại sao bạn thực hiện những thay đổi bạn đã thực hiện hoặc những gì họ phải hoàn thành. Luôn bao gồm tất cả các thông tin có liên quan khi bạn đăng, để mọi người sẽ biết tất cả những gì bạn đang làm. :)
DiMono

1
Điều này hoạt động vì nó không gây ra lỗi cho biết bạn không thể ghi vào tệp vừa tạo vì nó đang được sử dụng bởi một quy trình khác. .Dispose () là khóa. Cảm ơn bạn rất nhiều!
GenXisT

Điều này không theo bất kỳ cách nào giải quyết câu hỏi, đó là về việc giữ gìn nội dung hiện có.
Ben Voigt

Không có điểm nào để gọi Close()từ một usingtuyên bố, vì tất cả các tài nguyên sẽ bị đóng trước khi được xử lý tự động.
Sheridan

21

Bạn thực sự không phải kiểm tra xem tệp có tồn tại không, vì StreamWriter sẽ làm điều đó cho bạn. Nếu bạn mở nó ở chế độ chắp thêm, tập tin sẽ được tạo nếu nó không tồn tại, sau đó bạn sẽ luôn nối thêm và không bao giờ ghi quá nhiều. Vì vậy, kiểm tra ban đầu của bạn là dư thừa.

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

1
Tôi đã cố gắng tìm ra logic của câu trả lời được chấp nhận, tôi biết rằng tôi đã làm điều này trong một dòng trước đây nhưng không thể nhớ chính xác cú pháp. Cảm ơn bạn.
Morvael

14

File.AppendAllText thêm một chuỗi vào một tệp. Nó cũng tạo một tệp văn bản nếu tệp không tồn tại. Nếu bạn không cần đọc nội dung, nó rất hiệu quả. Các trường hợp sử dụng là đăng nhập.

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

Đây chỉ là những gì tôi cần, nhưng làm thế nào tôi có thể làm cho nội dung mới bắt đầu trên một dòng mới? Tôi đang sử dụng tệp CSV.
NiallUK

Tôi đoán không có một giải pháp đơn giản. Tôi sẽ đề nghị bạn kiểm tra bài đăng này. stackoverflow.com/questions/1343044/ cường
R.Cha


3

Khi bạn khởi động StreamWriter, nó sẽ ghi đè lên văn bản ở đó trước đó. Bạn có thể sử dụng chắp thêm tài sản như vậy:

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
Nếu bạn có khối 'sử dụng', w.Close là dự phòng. Vứt bỏ ở cuối sử dụng khối làm tương tự.
Michael Freidgeim

-1 Điều này tùy thuộc vào điều kiện chủng tộc và có thể tạo ra hành vi sai! Có lẽ nên sử dụng File.Open(path, FileMode.Append, FileAccess.ReadWrite)và kiểm tra kích thước tệp thông qua luồng trả về đó.
ComFalet


2

Thử cái này.

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), và với nó không cần phải kiểm tra File.Exists(path). Và If (not A) Else If (A)là một If / Else kỳ lạ. Về cơ bản không có điều gì tốt trong câu hỏi này, không có mã giải thích nào là phiên bản rút gọn của câu trả lời khác.
xdtTransform

-1 Điều này tùy thuộc vào điều kiện chủng tộc và có thể tạo ra hành vi sai! Có lẽ nên sử dụng File.Open(path, FileMode.Append, FileAccess.ReadWrite)và kiểm tra kích thước tệp thông qua luồng trả về đó.
ComFalet

2

Bạn chỉ có thể sử dụng Phương thức File.AppendAllText () điều này sẽ giải quyết vấn đề của bạn. Phương pháp này sẽ đảm nhiệm việc Tạo tệp nếu không có sẵn, mở và đóng tệp.

var outputPath = @"E:\Example.txt";
var data = "Example Data";
File.AppendAllText(outputPath, data);

1

Từ tài liệu microsoft, bạn có thể tạo tệp nếu không tồn tại và chắp thêm vào nó trong một cuộc gọi File.AppendAllText Phương thức (Chuỗi, Chuỗi)

.NET Framework (phiên bản hiện tại) Các phiên bản khác

Mở một tệp, nối thêm chuỗi đã chỉ định vào tệp và sau đó đóng tệp. Nếu tệp không tồn tại, phương thức này tạo một tệp, ghi chuỗi đã chỉ định vào tệp, sau đó đóng tệp. Không gian tên: Lắp ráp System.IO: mscorlib (trong mscorlib.dll)

Cú pháp C # C ++ F # VB public void void AppendAllText (đường dẫn chuỗi, nội dung chuỗi) Đường dẫn tham số Loại: System.String Tệp để nối chuỗi đã chỉ định vào. Nội dung Loại: System.String Chuỗi để nối vào tệp.

Append AllText


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

Nói chung, câu trả lời sẽ hữu ích hơn nhiều nếu chúng bao gồm một lời giải thích về những gì mã được dự định làm và tại sao điều đó giải quyết vấn đề mà không giới thiệu người khác.
Tim Diekmann
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.