Cara Menemukan Dan Mengganti Teks Dalam File Dengan C #

157

Kode saya sejauh ini

StreamReader reading = File.OpenText("test.txt");
string str;
while ((str = reading.ReadLine())!=null)
{
      if (str.Contains("some text"))
      {
          StreamWriter write = new StreamWriter("test.txt");
      }
}

Saya tahu cara menemukan teks, tetapi saya tidak tahu bagaimana cara mengganti teks dalam file dengan saya sendiri.

Menangkan Coder
sumber
Pertimbangkan komentar ini sebagai tip saja: Jika Anda memiliki studio visual, Anda dapat memasukkan folder dalam solusi dan menggunakan fitur pencarian dan ganti studio visual. Keberuntungan terbaik
StackOrder
Kemungkinan duplikat Buka file dan ganti string dalam C #
RecklessSergio

Jawaban:

322

Baca semua konten file. Lakukan penggantian dengan String.Replace. Tulis konten kembali ke file.

string text = File.ReadAllText("test.txt");
text = text.Replace("some text", "new value");
File.WriteAllText("test.txt", text);
Sergey Berezovskiy
sumber
5
@WinCoder BTW untuk penggantian yang lebih kompleks yang dapat Anda gunakanRegex.Replace
Sergey Berezovskiy
35
Ini membaca seluruh file ke memori sekaligus, tidak selalu sebagus itu.
Banshee
6
@Banshee Touche 'Saya baru saja mencoba membaca 9.000.000 baris dan terlempar System out of memorypengecualian.
Squ1rr3lz
4
Untuk file besar itu masalah yang lebih kompleks. Baca byte chunk, analisis, baca chunk lain, dll.
Alexander
6
@Alexander Benar. Satu potongan diakhiri dengan "... som", dan yang berikutnya dimulai dengan "e text ...". Membuatnya masalah yang jauh lebih rumit.
djv
36

Anda akan kesulitan menulis ke file yang sama dengan yang Anda baca. Salah satu cara cepat adalah dengan melakukan ini:

File.WriteAllText("test.txt", File.ReadAllText("test.txt").Replace("some text","some other text"));

Anda bisa menjelaskannya dengan lebih baik

string str = File.ReadAllText("test.txt");
str = str.Replace("some text","some other text");
File.WriteAllText("test.txt", str);
Flynn1179
sumber
3
Ini sederhana tetapi tidak diinginkan untuk file yang sangat besar. (ps Saya bukan orang yang downvoted)
Alvin Wong
3
Saya setuju, tetapi Anda tidak dapat menulis ke file saat Anda membacanya. Kecuali jika Anda menulis ke file yang berbeda, lalu ganti dengan mengganti nama setelahnya .. bagaimanapun, file baru harus disimpan di tempat lain saat Anda sedang membangunnya, apakah itu di memori atau di disk.
Flynn1179
@ Flynn1179 Tidak benar dalam contoh ini. Berhasil. Cobalah. Saya kira ReadAllTextmenutup akses file sebelum WriteAllText. Saya menggunakan teknik ini di aplikasi saya sendiri.
SteveCinq
Aku tahu; contoh ini tidak menulis saat sedang membaca, itu maksud saya!
Flynn1179
27

Anda perlu menulis semua baris yang Anda baca ke dalam file output, bahkan jika Anda tidak mengubahnya.

Sesuatu seperti:

using (var input = File.OpenText("input.txt"))
using (var output = new StreamWriter("output.txt")) {
  string line;
  while (null != (line = input.ReadLine())) {
     // optionally modify line.
     output.WriteLine(line);
  }
}

Jika Anda ingin melakukan operasi ini di tempat maka cara termudah adalah dengan menggunakan file output sementara dan pada akhirnya ganti file input dengan output.

File.Delete("input.txt");
File.Move("output.txt", "input.txt");

(Mencoba untuk melakukan operasi pembaruan di tengah file teks agak sulit untuk mendapatkan yang benar karena selalu memiliki penggantian dengan panjang yang sama adalah sulit mengingat sebagian besar pengkodean lebar variabel.)

EDIT: Daripada dua operasi file untuk mengganti file asli, lebih baik digunakan File.Replace("input.txt", "output.txt", null). (Lihat MSDN .)

Richard
sumber
1
VB harus mengubah 2 baris: Menggunakan input Sebagai StreamReader Baru (nama file) Sementara input.Peek ()> = 0
Brent
8

Kemungkinan Anda harus menarik file teks ke dalam memori dan kemudian melakukan penggantian. Anda kemudian harus menimpa file menggunakan metode yang Anda ketahui dengan jelas. Jadi, pertama-tama Anda akan:

// Read lines from source file.
string[] arr = File.ReadAllLines(file);

Anda kemudian dapat mengulang dan mengganti teks dalam array.

var writer = new StreamWriter(GetFileName(baseFolder, prefix, num));
for (int i = 0; i < arr.Length; i++)
{
    string line = arr[i];
    line.Replace("match", "new value");
    writer.WriteLine(line);
}

metode ini memberi Anda kendali atas manipulasi yang dapat Anda lakukan. Atau, Anda hanya bisa melakukan penggantian dalam satu baris

File.WriteAllText("test.txt", text.Replace("match", "new value"));

Saya harap ini membantu.

Ksatria bulan
sumber
6

Inilah yang saya lakukan dengan file besar (50 GB):

Saya mencoba 2 cara berbeda: yang pertama, membaca file ke dalam memori dan menggunakan Regex Replace atau String Replace. Kemudian saya menambahkan seluruh string ke file sementara.

Metode pertama berfungsi dengan baik untuk beberapa penggantian Regex, tetapi Regex.Replace atau String.Replace dapat menyebabkan kesalahan memori jika Anda melakukan banyak penggantian dalam file besar.

Yang kedua adalah dengan membaca file temp baris demi baris dan secara manual membangun setiap baris menggunakan StringBuilder dan menambahkan setiap baris yang diproses ke file hasil. Metode ini cukup cepat.

static void ProcessLargeFile()
{
        if (File.Exists(outFileName)) File.Delete(outFileName);

        string text = File.ReadAllText(inputFileName, Encoding.UTF8);

        // EX 1 This opens entire file in memory and uses Replace and Regex Replace --> might cause out of memory error

        text = text.Replace("</text>", "");

        text = Regex.Replace(text, @"\<ref.*?\</ref\>", "");

        File.WriteAllText(outFileName, text);




        // EX 2 This reads file line by line 

        if (File.Exists(outFileName)) File.Delete(outFileName);

        using (var sw = new StreamWriter(outFileName))      
        using (var fs = File.OpenRead(inFileName))
        using (var sr = new StreamReader(fs, Encoding.UTF8)) //use UTF8 encoding or whatever encoding your file uses
        {
            string line, newLine;

            while ((line = sr.ReadLine()) != null)
            {
              //note: call your own replace function or use String.Replace here 
              newLine = Util.ReplaceDoubleBrackets(line);

              sw.WriteLine(newLine);
            }
        }
    }

    public static string ReplaceDoubleBrackets(string str)
    {
        //note: this replaces the first occurrence of a word delimited by [[ ]]

        //replace [[ with your own delimiter
        if (str.IndexOf("[[") < 0)
            return str;

        StringBuilder sb = new StringBuilder();

        //this part gets the string to replace, put this in a loop if more than one occurrence  per line.
        int posStart = str.IndexOf("[[");
        int posEnd = str.IndexOf("]]");
        int length = posEnd - posStart;


        // ... code to replace with newstr


        sb.Append(newstr);

        return sb.ToString();
    }
cinta hidup
sumber
0

Kode ini bekerja untuk saya

- //-------------------------------------------------------------------
                           // Create an instance of the Printer
                           IPrinter printer = new Printer();

                           //----------------------------------------------------------------------------
                           String path = @"" + file_browse_path.Text;
                         //  using (StreamReader sr = File.OpenText(path))

                           using (StreamReader sr = new System.IO.StreamReader(path))
                           {

                              string fileLocMove="";
                              string newpath = Path.GetDirectoryName(path);
                               fileLocMove = newpath + "\\" + "new.prn";



                                  string text = File.ReadAllText(path);
                                  text= text.Replace("<REF>", reference_code.Text);
                                  text=   text.Replace("<ORANGE>", orange_name.Text);
                                  text=   text.Replace("<SIZE>", size_name.Text);
                                  text=   text.Replace("<INVOICE>", invoiceName.Text);
                                  text=   text.Replace("<BINQTY>", binQty.Text);
                                  text = text.Replace("<DATED>", dateName.Text);

                                       File.WriteAllText(fileLocMove, text);



                               // Print the file
                               printer.PrintRawFile("Godex G500", fileLocMove, "n");
                              // File.WriteAllText("C:\\Users\\Gunjan\\Desktop\\new.prn", s);
                           }
kekuatan radhason
sumber
0

saya cenderung menggunakan kode forward sederhana sebanyak yang saya bisa, kode di bawah ini bekerja dengan baik dengan saya

using System;
using System.IO;
using System.Text.RegularExpressions;

/// <summary>
/// Replaces text in a file.
/// </summary>
/// <param name="filePath">Path of the text file.</param>
/// <param name="searchText">Text to search for.</param>
/// <param name="replaceText">Text to replace the search text.</param>
static public void ReplaceInFile( string filePath, string searchText, string replaceText )
{
    StreamReader reader = new StreamReader( filePath );
    string content = reader.ReadToEnd();
    reader.Close();

    content = Regex.Replace( content, searchText, replaceText );

    StreamWriter writer = new StreamWriter( filePath );
    writer.Write( content );
    writer.Close();
}
Ali
sumber