2012-09-08 8 views
6

मैं अपनी स्ट्रिंग को फ़ाइल की शुरुआत में सम्मिलित करना चाहता हूं। लेकिन स्ट्रीम लेखक में शुरुआत में शामिल होने के लिए कोई फंक्शन नहीं है। तो मुझे यह कैसे करना चाहिए?स्ट्रीम राइटर के साथ फ़ाइल की शुरुआत में कैसे लिखना है?

मेरे कोड है:

string path = Directory.GetCurrentDirectory() + "\\test.txt"; 
StreamReader sreader = new StreamReader(path); 
string str = sreader.ReadToEnd(); 
sreader.Close(); 

StreamWriter swriter = new StreamWriter(path, false); 

swriter.WriteLine("example text"); 
swriter.WriteLine(str); 
swriter.Close(); 

लेकिन यह अनुकूलित प्रतीत नहीं होता। तो क्या कोई और तरीका है?

+1

लिए लेखन फ़ाइल की शुरुआत ओवरराइट होगी जो वहां है। शुरुआत के बजाय फ़ाइल के अंत में डेटा जोड़ने पर विचार करें। – Oded

+0

आपको पूरी फ़ाइल को पढ़ने की आवश्यकता होगी, इसे स्ट्रिंग में स्टोर करें, फिर 'स्ट्रिंग.इंटरर्ट' का उपयोग करके उस स्ट्रिंग की शुरुआत में अपना नया डेटा डालें, फिर संशोधित स्ट्रिंग के साथ पूरी फ़ाइल को फिर से लिखें। –

+0

@ 0 _______ 0 जैसा मैंने किया है। – hamed

उत्तर

8

आपने लगभग कर रहे हैं:

 string path = Directory.GetCurrentDirectory() + "\\test.txt"; 
     string str; 
     using (StreamReader sreader = new StreamReader(path)) { 
      str = sreader.ReadToEnd(); 
     } 

     File.Delete(path); 

     using (StreamWriter swriter = new StreamWriter(path, false)) 
     { 
      str = "example text" + Environment.NewLine + str; 
      swriter.Write(str); 
     } 
+0

+1। यह भी आसान 'नया स्ट्रीमवाइटर (पथ, सत्य)' फिक्स भी काम करेगा। –

+0

कोड संपादित करें: अनावश्यक 'हटाएं() 'कॉल -' उपयोग 'पहले से ही इसकी देखभाल कर रहा है। –

+3

उत्तर इस बात पर विचार नहीं करता है कि फ़ाइल का आकार वर्चुअल मेमोरी स्पेस के उपलब्ध क्षेत्र से अधिक हो सकता है। – SerG

4

आप अन्य प्रक्रियाओं एक ही फाइल और अपने प्रक्रिया के लिए लिखने पर विचार करने के लिए नहीं है, तो निर्देशिका, इस से निपटने के लिए होगा सबसे कारगर तरीका करने के लिए अनुमति बनवाने के :

  1. अस्थायी नाम के साथ नई फ़ाइल बनाना
  2. नया पाठ लिखने
  3. अपनी फ़ाइल से पुराने पाठ संलग्न
  4. हटाना फ़ाइल
  5. नाम बदलने अस्थायी फ़ाइल

यह अभ्यस्त है कि शांत और तेजी से हो सकता है, लेकिन कम से कम आप दृष्टिकोण आप अब उपयोग कर रहे हैं के लिए स्मृति में एक विशाल स्ट्रिंग आवंटित करने के लिए नहीं होगा।

हालांकि यदि आप सुनिश्चित हैं कि फाइलें छोटे होने जा रही हैं, जैसे कि कई मेगाबाइट्स से भी कम, आपका दृष्टिकोण इतना बुरा नहीं है।

लेकिन आप संभव अपने कोड थोड़ा आसान बनाने में कर सकते हैं:

public static void InsertText(string path, string newText) 
{ 
    if (File.Exists(path)) 
    { 
     string oldText = File.ReadAllText(path); 
     using (var sw = new StreamWriter(path, false)) 
     { 
      sw.WriteLine(newText); 
      sw.WriteLine(oldText); 
     } 
    } 
    else File.WriteAllText(path,newText); 
} 

और बड़ी फ़ाइलों (यानी> कई एमबी)

public static void InsertLarge(string path, string newText) 
{ 
    if(!File.Exists(path)) 
    { 
     File.WriteAllText(path,newText); 
     return; 
    } 

    var pathDir = Path.GetDirectoryName(path); 
    var tempPath = Path.Combine(pathDir, Guid.NewGuid().ToString("N")); 
    using (var stream = new FileStream(tempPath, FileMode.Create, 
     FileAccess.Write, FileShare.None, 4 * 1024 * 1024)) 
    { 
     using (var sw = new StreamWriter(stream)) 
     { 
      sw.WriteLine(newText); 
      sw.Flush(); 
      using (var old = File.OpenRead(path)) old.CopyTo(sw.BaseStream); 
     } 
    } 
    File.Delete(path); 
    File.Move(tempPath,path); 
} 
+0

आपको स्पष्ट रूप से बैकिंग फ़ाइलस्ट्रीम बनाने की आवश्यकता क्यों है? – SerG

+0

सेरग, यह कुछ समय पहले था, लेकिन मैं शर्त लगाता हूं क्योंकि यह बफर आकार के साथ अधिभार प्रदान करता है। – aiodintsov

0

कुछ इस तरह के लिए:

private void WriteToFile(FileInfo pFile, string pData) 
    { 
     var fileCopy = pFile.CopyTo(Path.GetTempFileName(), true); 

     using (var tempFile = new StreamReader(fileCopy.OpenRead())) 
     using (var originalFile = new StreamWriter(File.Open(pFile.FullName, FileMode.Create))) 
     { 
      originalFile.Write(pData); 
      originalFile.Write(tempFile.ReadToEnd()); 
      originalFile.Flush(); 
     } 

     fileCopy.Delete(); 
    }