2019-06-15

[ASP.NET] FileStream 只讀到第一列

有個需求是這樣的,每 60 秒會接收一次資料進來,每次有 60 筆,收進來的資料要存成檔案,所以用了以下程式來存成 Data.Json 檔:
// 資料 Append 到檔案 Data.Json
ConcurrentDictionary<int, Data> tempData = new ConcurrentDictionary<int, Data>();
...(略)

using (FileStream stream = new FileStream("Data.json", FileMode.Append))
{
    BinaryFormatter bformatter = new BinaryFormatter();
    bformatter.Serialize(stream, tempData);
}

然後等到有需要時,就用以下程式讀取 Data.Json 裡的資料出來:
// 載入Data.Json
ConcurrentDictionary<int, Data> realData = new ConcurrentDictionary<int, Data>();

if (File.Exists("Data.json"))
{
    using (FileStream stream = new FileStream("Data.json", FileMode.Open))
    {
        BinaryFormatter bformatter = new BinaryFormatter();
        realData = (ConcurrentDictionary<int, AccPullerData>)bformatter.Deserialize(stream);  
    }
}

但是讀取到的資料都只有前 60 筆,原來 FileStream 每次 Append 資料時,都屬於不同的 Position,而在 Read 時只會一次讀取一個 Position,所以以上的寫法只會取到第一個 Position。

需加上判斷是否已經讀到最後了才行,如下:
// 載入Data.Json
ConcurrentDictionary<int, Data> realData = new ConcurrentDictionary<int, Data>();

if (File.Exists("Data.json"))
{
    using (FileStream stream = new FileStream("Data.json", FileMode.Open))
    {
        BinaryFormatter bformatter = new BinaryFormatter();

        // 判斷是否已經讀到最後了
        while (stream.Position != stream.Length)
        {
            var temp = (ConcurrentDictionary<int, Data>)(bformatter.Deserialize(stream));
            foreach (var item in temp)
                realData.TryAdd(item.Key, item.Value);
        }
    }
}



參考來源:stackOverflow

沒有留言:

張貼留言