การสร้างไฟล์เปล่าใน C #


186

วิธีที่ง่ายที่สุด / บัญญัติในการสร้างไฟล์ว่างใน C # /. NET คืออะไร?

วิธีที่ง่ายที่สุดที่ฉันสามารถหาได้คือ:

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

คำตอบ:


384

การใช้เพิ่งFile.Createจะเปิดไฟล์ไว้ซึ่งอาจไม่ใช่สิ่งที่คุณต้องการ

คุณสามารถใช้:

using (File.Create(filename)) ;

ดูแปลกไปเล็กน้อย คุณสามารถใช้เครื่องมือจัดฟันแทน:

using (File.Create(filename)) {}

หรือเพียงโทรDisposeโดยตรง:

File.Create(filename).Dispose();

ไม่ว่าจะด้วยวิธีใดหากคุณจะใช้งานในสถานที่มากกว่าหนึ่งแห่งคุณควรพิจารณาห่อด้วยวิธีการช่วยเหลือเช่น

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

โปรดทราบว่าโทรDisposeโดยตรงแทนการใช้usingคำสั่งไม่ได้จริงๆให้แตกต่างกันมากที่นี่เท่าที่ผมสามารถบอกได้ - วิธีเดียวที่จะสามารถสร้างความแตกต่างคือถ้าด้ายถูกยกเลิกระหว่างการเรียกและเรียกร้องให้File.Create Disposeถ้าว่าสภาพการแข่งขันที่มีอยู่ผมสงสัยว่ามันจะยังมีอยู่ในusingรุ่นถ้าด้ายถูกยกเลิกที่ปลายสุดของFile.Createวิธีการก่อนค่าที่ถูกส่งกลับ ...


8
ตลก. ฉันเพิ่งเขียนรหัสเดียวกันประมาณ 5 นาทีที่ผ่านมา ฉันทำ File.Create (ชื่อไฟล์) .Close (); ต่างกัน ...
Brian Genisio

2
รหัสของฉันใช้using (File.Create(filename)) ;งานอยู่ แต่ฉันชอบความเรียบง่ายของFile.Create(filename).Dispose();
Vadim

@BrianGenisio: ฉันเพิ่งทำรหัสเดียวกันประมาณ 5 นาทีที่แล้วด้วย! ฉันเพิ่งไปดูว่าโปรแกรมเมอร์คนอื่นทำอย่างไร ตอนนี้ฉันใช้File.Create(filename).Dispose();แทน
แจ็ค

1
@ user3791372: Close()จะปล่อยทรัพยากรเช่นกัน Close()เพียงแค่โทรDispose- ดูgithub.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/ ......
Jon Skeet

1
อาจไม่ชัดเจนว่าหากไฟล์นั้นมีอยู่แล้วและไม่ได้เป็นแบบอ่านอย่างเดียวเนื้อหาของไฟล์จะถูกเขียนทับ เพื่อหลีกเลี่ยงปัญหานี้ให้ใช้using (new FileStream(filename, FileMode.CreateNew)) { }
Phil Haselden

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

หรือ

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

2
เมื่อใช้ครั้งแรกไฟล์จะมีความยาว 3 ไบต์: รหัสการเข้ารหัส การใช้ไฟล์ที่สองคือ 0 ไบต์ (ว่างเปล่าจริงๆ)
Fil

1
@Fil: คุณแน่ใจเหรอ? เอกสารกล่าวว่าFile.WriteAllText(string, string)การใช้"เข้ารหัส UTF-8 โดยไม่ต้องมาร์คลำดับไบต์ (BOM)" หากคุณยังคงเห็นข้อผิดพลาดหนึ่งนั่นอาจเป็นข้อผิดพลาดใน WriteAllText หรือเอกสารของมูลค่าการรายงาน
Heinzi

ฉันจำได้ว่าฉันได้ลองแล้ว อาจเป็นข้อผิดพลาดเก่าของรุ่น. Net รุ่นก่อนหน้าใช่หรือไม่ ไฟล์ไม่ว่างเปล่าหากฉันระบุอย่างชัดเจนให้ใช้การเข้ารหัส UTF8 (หรือ unicode หรืออย่างอื่น): <File.WriteAllText ("c: \ del.txt", String.Empty, System.Text.Encoding.UTF8);
Fil

1
@Fil Encoding.UTF8ส่งคืนตัวเข้ารหัสที่ส่งออก Byte Order Mark (BOM) คุณสามารถใช้new UTF8Encoding(false)เพื่อรับตัวเข้ารหัส UTF8 ที่ไม่ส่งออก BOM
Daniel Crabtree

1
ไม่ทราบว่าWriteAllTextแตกต่างจากรุ่นก่อนหน้าของ. NET หรือไม่ อย่างไรก็ตามเพื่อความแน่ใจเป็นพิเศษให้ข้ามส่วนการเข้ารหัสและใช้File.WriteAllBytes(path, new byte[] { });แทน
Jürgen Steinblock

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

ตามที่คนอื่น ๆ ได้ชี้ให้เห็นคุณควรกำจัดวัตถุนี้หรือห่อไว้ในที่ว่างโดยใช้คำสั่ง

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

4
จะไม่ดีกว่าการกำจัดวัตถุ? เช่น: using (System.IO.File.Create (filepath)) {}
kentaromiura

@kentaromiura: ความคิดของฉันว่าด้วยเหตุนี้คำตอบของฉัน :)
จอนสกีต

4

คุณสามารถโยงเมธอดออกจากอ็อบเจ็กต์ที่ส่งคืนดังนั้นคุณสามารถปิดไฟล์ที่คุณเพิ่งเปิดในคำสั่งเดียวได้ทันที

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

4

เพื่อหลีกเลี่ยงการเขียนทับไฟล์ที่มีอยู่โดยไม่ได้ตั้งใจ:

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

... และจัดการกับ IOException ซึ่งจะเกิดขึ้นหากไฟล์นั้นมีอยู่แล้ว

File.Createซึ่งมีคำแนะนำในคำตอบอื่น ๆ จะเขียนทับเนื้อหาของหากไฟล์นั้นมีอยู่แล้ว ในกรณีง่าย ๆ คุณสามารถลดการใช้นี้File.Exists()ได้ อย่างไรก็ตามจำเป็นต้องมีบางสิ่งที่แข็งแกร่งกว่าในสถานการณ์ที่หลายเธรดและ / หรือกระบวนการพยายามสร้างไฟล์ในโฟลเดอร์เดียวกันพร้อมกัน


2

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

ดังนั้นจึงสามารถช่วยในการสร้างชื่อขยะ (Guid.NewGuid.ToString ()) ในไดเรกทอรีเดียวกับไฟล์ที่คุณต้องการสร้างแล้วทำ File.Move จากชื่อชั่วคราวเป็นชื่อที่คุณต้องการ มิฉะนั้นรหัสที่ทริกเกอร์ซึ่งตรวจสอบการมีอยู่ของไฟล์และจากนั้นลบทริกเกอร์อาจทำงานในสภาพการแข่งขันที่ไฟล์ถูกลบก่อนที่จะปิดอย่างสมบูรณ์

การมีไฟล์ temp ในไดเรกทอรีเดียวกัน (และระบบไฟล์) จะช่วยให้คุณมีอะตอมมิกซิตี้ที่คุณอาจต้องการ มันให้อะไรทำนองนี้

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 () จะสร้างไฟล์ว่างชื่อ uniquly และส่งคืนพา ธ

ถ้าคุณต้องการควบคุมพา ธ แต่รับชื่อไฟล์แบบสุ่มคุณสามารถใช้ GetRandomFileName เพื่อส่งคืนสตริงชื่อไฟล์และใช้กับสร้าง

ตัวอย่างเช่น:

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

IMHO GetTempFileName () มีการใช้ชื่อผิดอย่างสมบูรณ์
kay.herzam

ทำไมคำตอบนี้ไม่เป็นประโยชน์จริง ๆ ?
Crippledsmurf

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

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