[.NET]大檔案的 Replace, Split 方式

最近同事在做檔案匯入時,需要用透過 BinaryReader 取出資料後,

需要再進行 Replace 及 Split。

有時會發生 OutOfMemory 的 Exception。

 

測試的程式如下,

string bigFile = @"很大的檔案";
var file = new FileStream(bigFile, FileMode.Open);
using (BinaryReader reader = new BinaryReader(file))
{
	var orgData = reader.ReadBytes(Convert.ToInt32(file.Length));
	var allStr = BitConverter.ToString(orgData);
	//在有些檔案中 replace 會有 OutOfMemory 的 Exception 
	var removedDataStr = allStr.Replace("-", string.Empty);
	var hexArray = Regex.Split(removedDataStr, "0D0A", RegexOptions.IgnoreCase);
}

一開始讀取檔案出來後需要將裡面的 - 移除後,再依 0D0A 來切分成不同的字串,

最後再將 Split 的資料回傳。

但是這樣子都在操系統的 Memory ,而且等結果回來需要很久的時間。

ps. 不小心在上面按下中斷點,VS.NET 可能就會 Busy ... 哦!

 

我們也可以改用 IEnumerable 的方式來處理,如以下的Code,回應時間就快多了。

string bigFile = @"很大的檔案";
var file = new FileStream(bigFile, FileMode.Open);
using (BinaryReader reader = new BinaryReader(file))
{
	var orgData = reader.ReadBytes(Convert.ToInt32(file.Length));
	var allStr = BitConverter.ToString(orgData);
	var removedData = allStr.Where(s => s != '-');
	var removedSplits = Split2(removedData, "0D0A");
	//或許可以先加 Take 幾筆資料出來比對一下,沒問題再往下處理 
	//var removedSplits = Split2(removedData, "0D0A").Take(5);
	foreach(string line in removedSplits){
		Console.WriteLine(line);
		//可以在這裡一個一個的處理
	}
		
}

public static IEnumerable<string> Split2(IEnumerable<char> source, string splitStr)
{
	var enumerator = source.GetEnumerator();
	string line = string.Empty;
	while (enumerator.MoveNext())
	{
		line += (char)enumerator.Current;
		if (line.EndsWith(splitStr))
		{
			yield return line.Substring(0, line.Length - splitStr.Length);
			Console.WriteLine(line);
			line = string.Empty;
		}
	}
}

 

Hi, 

亂馬客Blog已移到了 「亂馬客​ : Re:從零開始的軟體開發生活

請大家繼續支持 ^_^