Tạo một tệp trống trong C #


185

Cách đơn giản / kinh điển nhất để tạo một tệp trống trong C # /. NET là gì?

Cách đơn giản nhất tôi có thể tìm thấy cho đến nay là:

System.IO.File.WriteAllLines(filename, new string[0]);

Câu trả lời:


384

Sử dụng chỉ File.Createđể lại các tập tin mở, có thể không phải là những gì bạn muốn.

Bạn đã có thể sử dụng:

using (File.Create(filename)) ;

Điều đó có vẻ hơi kỳ lạ, nhớ bạn. Bạn có thể sử dụng niềng răng thay thế:

using (File.Create(filename)) {}

Hoặc chỉ cần gọi Disposetrực tiếp:

File.Create(filename).Dispose();

Dù bằng cách nào, nếu bạn sẽ sử dụng điều này ở nhiều nơi, có lẽ bạn nên xem xét việc bọc nó trong một phương thức trợ giúp, ví dụ:

public static void CreateEmptyFile(string filename)
{
    File.Create(filename).Dispose();
}

Lưu ý rằng gọi Disposetrực tiếp thay vì sử dụng usingcâu lệnh không thực sự tạo ra nhiều khác biệt ở đây theo như tôi có thể nói - cách duy nhất có thể tạo ra sự khác biệt là nếu chuỗi bị hủy bỏ giữa cuộc gọi đến File.Createvà cuộc gọi đến Dispose. Nếu điều kiện chủng tộc đó tồn tại, tôi nghi ngờ nó cũng sẽ tồn tại trong usingphiên bản, nếu luồng bị hủy bỏ ở cuối File.Createphương thức, ngay trước khi giá trị được trả về ...


8
Buồn cười. Tôi chỉ viết cùng một mã khoảng 5 phút trước. Tôi đã làm File.Create (tên tệp) .Close (); Cùng khác ...
Brian Genisio

2
Mã của tôi đã được sử dụng using (File.Create(filename)) ;, nhưng tôi yêu sự đơn giản củaFile.Create(filename).Dispose();
Vadim

@BrianGenisio: Tôi cũng vừa làm mã tương tự khoảng 5 phút trước! Tôi chỉ googled để xem các lập trình viên khác đã làm điều đó như thế nào. Bây giờ tôi đang sử dụng File.Create(filename).Dispose();thay vì.
Jack

1
@ user3791372: Close()cũng sẽ phát hành các tài nguyên. Close()chỉ cần gọi Dispose- xem github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/ trộm
Jon Skeet

1
Có thể không rõ ràng rằng nếu tệp đã tồn tại và không chỉ đọc, nội dung tệp sẽ bị ghi đè. Để tránh điều này, hãy sử dụngusing (new FileStream(filename, FileMode.CreateNew)) { }
Phil Haselden

34
File.WriteAllText("path", String.Empty);

hoặc là

File.CreateText("path").Close();

2
Sử dụng đầu tiên, tệp dài 3 byte: mã hóa. Sử dụng tệp thứ hai là 0 byte (thực sự trống).
Fil

1
@Fil: Bạn có chắc không? Tài liệu nói rằng File.WriteAllText(string, string)sử dụng "mã hóa UTF-8 mà không có Dấu thứ tự (BOM)" . Nếu bạn vẫn thấy một lỗi, đó sẽ là một lỗi trong WriteAllText hoặc tài liệu đáng báo cáo.
Heinzi

Tôi nhớ tôi đã thử. Có lẽ đó là một lỗi cũ của phiên bản .Net trước đó? Tệp không trống nếu tôi chỉ định rõ ràng sử dụng mã hóa UTF8 (hoặc unicode hoặc thứ gì khác): <File.WriteAllText ("c: \ del.txt", String.Empty, System.Text.Encoding.UTF8);>
Fil

1
@Fil, Encoding.UTF8trả về một bộ mã hóa xuất ra Dấu thứ tự Byte (BOM). Bạn có thể sử dụng new UTF8Encoding(false)để có được bộ mã hóa UTF8 không xuất BOM.
Daniel Crabtree

1
Không biết nếu WriteAllTextthực sự hành xử khác nhau trong phiên bản .NET trước. Tuy nhiên, để chắc chắn hơn, chỉ cần bỏ qua phần mã hóa và sử dụng File.WriteAllBytes(path, new byte[] { });thay thế.
Jürgen Steinblock

20
System.IO.File.Create(@"C:\Temp.txt");

Như những người khác đã chỉ ra, bạn nên loại bỏ đối tượng này hoặc bọc nó trong một câu lệnh trống bằng cách sử dụng.

using (System.IO.File.Create(@"C:\Temp.txt"));

4
Sẽ tốt hơn để xử lý các đối tượng? ví dụ: bằng cách sử dụng (System.IO.File.Create (filepath)) {}
kentaromiura

@kentaromiura: Chính xác là suy nghĩ của tôi, vì vậy câu trả lời của tôi :)
Jon Skeet

4

Bạn có thể xâu chuỗi các phương thức khỏi đối tượng được trả về, vì vậy bạn có thể đóng ngay tệp bạn vừa mở trong một câu lệnh.

File.Open("filename", FileMode.Create).Close();

4

Để tránh vô tình ghi đè một tập tin hiện có, hãy sử dụng:

using (new FileStream(filename, FileMode.CreateNew)) {}

... và xử lý IOException sẽ xảy ra nếu tệp đã tồn tại.

File.Create, được đề xuất trong các câu trả lời khác, sẽ ghi đè lên nội dung nếu tệp đã tồn tại. Trong trường hợp đơn giản, bạn có thể giảm thiểu điều này bằng cách sử dụng File.Exists(). Tuy nhiên, một cái gì đó mạnh mẽ hơn là cần thiết trong các tình huống trong đó nhiều luồng và / hoặc các tiến trình đang cố gắng tạo các tệp trong cùng một thư mục.


2

Một trường hợp sử dụng khá phổ biến để tạo một tệp trống là để kích hoạt một cái gì đó khác xảy ra trong một quy trình khác trong trường hợp không tinh vi hơn trong giao tiếp quy trình. Trong trường hợp này, việc tạo tệp có thể là nguyên tử theo quan điểm của thế giới bên ngoài (đặc biệt nếu điều được kích hoạt sẽ xóa tệp để "tiêu thụ" trình kích hoạt).

Vì vậy, nó có thể giúp tạo một tên rác (Guid.NewGuid.ToString ()) trong cùng thư mục với tệp bạn muốn tạo, sau đó thực hiện File.Move từ tên tạm thời sang tên bạn muốn. Mặt khác, mã được kích hoạt để kiểm tra sự tồn tại của tệp và sau đó xóa kích hoạt có thể chạy trong điều kiện cuộc đua trong đó tệp bị xóa trước khi nó bị đóng hoàn toàn.

Có tệp tạm thời trong cùng thư mục (và hệ thống tệp) mang lại cho bạn tính nguyên tử mà bạn có thể muốn. Điều này cho một cái gì đó như.

public void CreateEmptyFile(string path)
{
    string tempFilePath = Path.Combine(Path.GetDirectoryName(path),
        Guid.NewGuid.ToString());
    using (File.Create(tempFilePath)) {}
    File.Move(tempFilePath, path);
}

0

Path.GetTempFileName () sẽ tạo một tệp trống có tên duy nhất và trả về đường dẫn đến nó.

Nếu bạn muốn kiểm soát đường dẫn nhưng lấy tên tệp ngẫu nhiên, bạn có thể sử dụng GetRandomFileName để chỉ trả về chuỗi tên tệp và sử dụng nó với Tạo

Ví dụ:

string fileName=Path.GetRandomFileName();
File.Create("custom\\path\\" + fileName);

IMHO GetTempFileName () được đặt tên sai hoàn toàn.
kay.herzam

Tại sao chính xác câu trả lời này không hữu ích?
tê liệt

5
Thật vô ích vì hai lý do: 1. Câu hỏi không hỏi gì về việc tạo tên tệp ngẫu nhiên, vì vậy đó là một sự phân tâm. 2. Tệp không bị đóng, điều đó có nghĩa là nếu sau này bạn cố gắng mở trình ghi tệp khác hoặc di chuyển tệp, nó sẽ thất bại.
Sông Satya

Tôi lấy điểm của bạn nhưng: 1. Tất cả các tệp cần một tên. Đó là một đơn giản. Cách thuận tiện để có được một thứ không có khả năng va chạm với bất cứ thứ gì 2. Câu hỏi được hỏi về việc tạo tệp, mà mã được đề cập, tối thiểu, việc quản lý tệp sau đó không hoàn toàn là một phần của việc tạo, vì vậy tôi đã bỏ qua nó cho vì đơn giản và giữ câu trả lời tập trung vào câu hỏi
Cripplingsmurf
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.