Ton*_*ich 377 .net c# bytearray binary-data
我有一个Web服务器,它将大型二进制文件(几兆字节)读入字节数组.服务器可能同时读取多个文件(不同的页面请求),所以我正在寻找最优化的方法来做到这一点,而不会对CPU造成过多的负担.下面的代码是否足够好?
public byte[] FileToByteArray(string fileName)
{
byte[] buff = null;
FileStream fs = new FileStream(fileName,
FileMode.Open,
FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
long numBytes = new FileInfo(fileName).Length;
buff = br.ReadBytes((int) numBytes);
return buff;
}
Run Code Online (Sandbox Code Playgroud)
Meh*_*ari 754
只需用以下内容替换整个内容:
return File.ReadAllBytes(fileName);
Run Code Online (Sandbox Code Playgroud)
但是,如果您担心内存消耗,则不应该一次性将所有文件都读入内存.你应该以大块的方式做到这一点.
Mar*_*ell 66
我可能会争辩说这里的答案通常是"不要".除非您绝对需要同时使用所有数据,否则请考虑使用Stream基于API的API(或读取器/迭代器的某些变体).当您有多个并行操作(如问题所示)以最小化系统负载和最大化吞吐量时,这一点尤为重要.
例如,如果要将数据流式传输给调用者:
Stream dest = ...
using(Stream source = File.OpenRead(path)) {
byte[] buffer = new byte[2048];
int bytesRead;
while((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) {
dest.Write(buffer, 0, bytesRead);
}
}
Run Code Online (Sandbox Code Playgroud)
Pow*_*ord 32
我会这样想:
byte[] file = System.IO.File.ReadAllBytes(fileName);
Run Code Online (Sandbox Code Playgroud)
小智 25
您的代码可以考虑到这一点(代替File.ReadAllBytes):
public byte[] ReadAllBytes(string fileName)
{
byte[] buffer = null;
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
buffer = new byte[fs.Length];
fs.Read(buffer, 0, (int)fs.Length);
}
return buffer;
}
Run Code Online (Sandbox Code Playgroud)
请注意Integer.MaxValue - Read方法放置的文件大小限制.换句话说,您一次只能读取2GB的块.
另请注意,FileStream的最后一个参数是缓冲区大小.
我还建议阅读有关FileStream和BufferedStream的内容.
一如既往的简单示例程序,以最快的速度分析将是最有益的.
您的底层硬件也会对性能产生很大影响.您是否使用具有大缓存的服务器硬盘驱动器和带有板载内存缓存的RAID卡?或者您使用连接到IDE端口的标准驱动器?
小智 9
根据操作频率,文件大小以及您正在查看的文件数量,还有其他性能问题需要考虑.要记住的一件事是,每个字节数组都将被垃圾收集器释放.如果您没有缓存任何这些数据,最终可能会造成大量垃圾,并且会使您的大部分性能损失到GC中的时间.如果块大于85K,你将分配大对象堆(LOH),这将需要所有代的集合来释放(这是非常昂贵的,并且在服务器上将停止所有执行,而它正在进行).此外,如果您在LOH上有大量对象,则最终可能会出现LOH碎片(LOH从未压缩),这会导致性能不佳和内存不足异常.一旦达到某一点,您就可以回收该过程,但我不知道这是否是最佳做法.
关键是,您应该考虑应用程序的整个生命周期,然后才能以最快的方式将所有字节读入内存,或者您可能会为整体性能进行短期性能交易.
我会说BinaryReader很好,但可以重构,而不是用于获取缓冲区长度的所有代码行:
public byte[] FileToByteArray(string fileName)
{
byte[] fileData = null;
using (FileStream fs = File.OpenRead(fileName))
{
using (BinaryReader binaryReader = new BinaryReader(fs))
{
fileData = binaryReader.ReadBytes((int)fs.Length);
}
}
return fileData;
}
Run Code Online (Sandbox Code Playgroud)
应该比使用更好的.ReadAllBytes(),因为我在包括顶部响应的意见看到.ReadAllBytes(),该提意见的人有问题的文件> 600 MB,因为BinaryReader是为这样的事情.此外,将其放在一个using声明中可确保FileStream并BinaryReader关闭和处理.
| 归档时间: |
|
| 查看次数: |
462381 次 |
| 最近记录: |