นี่คือวิธีที่ฉันทำกับไฟล์ขนาดใหญ่ (50 GB):
ฉันลองวิธีที่ต่างกัน 2 วิธี: วิธีแรกคืออ่านไฟล์ในหน่วยความจำและใช้ Regex Replace หรือ String Replace จากนั้นฉันต่อท้ายสตริงทั้งหมดลงในไฟล์ชั่วคราว
วิธีแรกทำงานได้ดีสำหรับการเปลี่ยน Regex สองสามครั้ง แต่ Regex.Replace หรือ String.Replace อาจทำให้เกิดข้อผิดพลาดของหน่วยความจำไม่ได้หากคุณทำการแทนที่หลายครั้งในไฟล์ขนาดใหญ่
ข้อที่สองคือการอ่านไฟล์ temp ทีละบรรทัดและสร้างแต่ละบรรทัดด้วยตนเองโดยใช้ StringBuilder และต่อท้ายแต่ละบรรทัดที่ประมวลผลไปยังไฟล์ผลลัพธ์ วิธีนี้ค่อนข้างเร็ว
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();
}