一、場景:
需要將有一定格式的File里的內容讀取到已經定義的類中,譬如一個二進制文件里的內容讀取到一個新的DataStructure里面。
1. File不是很大,一次將所有內容Load到內存中,不會占用太多Memory;
2. 二進制文件無法直接反序列化成一個Object,需要一個映射才能完成轉換.
二、為什么不用FileStream:
首先,我們來看一下FileStream的代碼以及原理:
FileStream fs = new FileStream(binaryFilePath, FileMode.Open, FileAccess.Read);
Encoding enc = Encoding.ASCII;
using (BinaryReader br = new BinaryReader(fs,enc))
{
//
}
BinaryReader 提供了ReadInt16,ReadChar,ReadDouble,……但是每次Position.Seek都會去定位流的指針,所以會耗費一些時間。
但是如果我們一次性的將所有內容都獨到內存(Memory)中,然后操作Memory是不是更快呢?
三、MemoryStream實現方法
FileStream fs = new FileStream(binaryFilePath, FileMode.Open, FileAccess.Read);
//Read all bytes into an array from the specified file.
int nBytes = (int)fs.Length;//計算流的長度
byte[] byteArray = new byte[nBytes];//初始化用於MemoryStream的Buffer
int nBytesRead = fs.Read(byteArray, 0, nBytes);//將File里的內容一次性的全部讀到byteArray中去
using (MemoryStream br = new MemoryStream(byteArray))//初始化MemoryStream,並將Buffer指向FileStream的讀取結果數組
{
/your code
}
四、性能分析
分別用以上兩種方法Load File:1,2,3,4,5,6,將其Load的時間記錄下來:
File | File Size(Mb) | FileStream(ms) | MemoryStream(ms) | Performance Enhancement |
1 | 0.5 | 921 | 392 | 2.35 |
2 | 7.1 | 4454 | 1466 | 3.04 |
3 | 14 | 7848 | 3366 | 2.33 |
4 | 28 | 16025 | 6242 | 2.57 |
5 | 44 | 21196 | 9268 | 2.26 |
6 | 73 | 27533 | 14503 | 1.90 |
可以看出:應用了MemoryStream性能提高了2-3倍。
可以看出:隨着File內容的增加,性能提高的就越來越緩慢,因為他占用了更多的內存空間,可以說是:“以空間換時間”。