最近同事在做檔案匯入時,需要用透過 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:從零開始的軟體開發生活」
請大家繼續支持 ^_^