0

目前,当我读取 15Mb 文件时,我的应用程序会占用大量内存。请注意,在主代码的末尾,我将插入数据库中的数据与文件中的原始数组进行比较。欢迎任何建议。

主要代码:

TestEntities entities = new TestEntities();

        using (FileStream fileStream = new FileStream(fileName + ".exe", FileMode.Open, FileAccess.Read))
        {

            byte[] bytes = new byte[fileStream.Length];

            int numBytesToRead = (int) fileStream.Length;
            int numBytesRead = 0;

            while (numBytesToRead > 0)
            {
                int n = fileStream.Read(bytes, numBytesRead, numBytesToRead);

                if (n == 0)
                    break;

                numBytesRead += n;
                numBytesToRead -= n;
            }

            var query = bytes.Select((x, i) => new {Index = i, Value = x})
                .GroupBy(x => x.Index/100)
                .Select(x => x.Select(v => v.Value).ToList())
                .ToList();

            foreach (List<byte> list in query)
            {
                Binary binary = new Binary();
                binary.Name = fileName + ".exe";
                binary.Value = list.ToArray();
                entities.AddToBinaries(binary);
            }

            entities.SaveChanges();

            List<Binary> fileString = entities.Binaries.Where(b => b.Name == fileName + ".exe").ToList();

            Byte[] final = ExtractArray(fileString);
            if (Compare(bytes, final))
            {
                 /// Some notification that was ok
            }

        }

比较方法:

public bool Compare(Byte[] array1,Byte[] array2)
    {
        bool isEqual = false;
        if (array1.Count() == array2.Count())
        {

            for (int i = 0; i < array1.Count(); i++)
            {
                isEqual = array1[i] == array2[i];
                if (!isEqual)
                {
                    break;

                }
            }
        }


        return isEqual;
    }

ExtractArray 方法:

public Byte[] ExtractArray(List<Binary> binaries )
    {
        List<Byte> finalArray = new List<Byte>();

        foreach (Binary binary in binaries)
        {
            foreach (byte b in binary.Value)
            {
                finalArray.Add(b);
            }

        }

        return finalArray.ToArray();
    }
4

3 回答 3

2

对于初学者,我强烈建议您投资分析器。这是确定您的代码为何需要如此长时间才能运行或使用大量内存的正确方法。那里有许多分析器,如果您拥有 Premium 或 Ultimate ,包括Visual Studio 2010 中内置的一个。

其他人见谷歌或这些帖子:

有哪些好的 .NET 分析器?

最好的 .NET 内存和性能分析器?

其次,您可能不应该假设您的应用程序不应该占用大量内存。C# 应用程序(实际上,所有 .NET 应用程序)都会被垃圾回收。如果我有一台有足够 RAM 的计算机,那么在没有内存压力的情况下,没有理由运行 GC,如果没有,应用程序很容易用完内存。对于 64 位环境尤其如此,其中进程不受 32 位地址空间的内存限制。

于 2012-04-19T06:41:04.310 回答
0

1)你知道静态方法File.ReadAllBytes吗?可以为您节省前 15 行代码。

2)我讨厌 Linq... 不可读,很难理解到底发生了什么。

        var query = bytes.Select((x, i) => new {Index = i, Value = x})
            .GroupBy(x => x.Index/100)
            .Select(x => x.Select(v => v.Value).ToList())
            .ToList();

因此,对于文件的每个字节,您都创建了一个包含字节本身及其索引的对象。哇。如果你的文件是 15mb,那就是 15 728 640 个对象。假设这个对象占用 64 个字节,即 960mb 的内存空间。

顺便说一句,你想做什么?

编辑

var bytes = File.ReadAllBytes(filename);

var chunkCount = (int)Math.Ceilling(bytes.Length / 100.0);

var chunks = new List<ArraySegment<byte>>(chunkCount);


for(int i = 0; i < chunkCount; i++) {
  chunks.Add(new ArraySegment(
      bytes,
      i * 100,
      Math.Min(100, bytes.Length - i * 100)
  ));
}

这应该快几倍。

尽管如此,为了获得更好的性能,您可能会在读取文件时在数据库中插入块,而不会将所有这些字节保留在内存中。

于 2012-04-19T07:09:39.707 回答
0

首先是comapre的两个变体:

bool arraysAreEqual = Enumerable.SequenceEqual(array1, array2);

或者这个

    public bool Compare(Byte[] array1, Byte[] array2)
    {
        if (array1.Length != array2.Length)
            return false;

        for (int i = 0; i < array1.Length; i++)
        {
            if (array1[i] != array2[i])
                return false;
        }
        return true;            
    }

关于提取试试这个:

foreach (Binary binary in binaries)
{
     finalArray.AddRange(binary.Value);
}
于 2012-04-19T06:41:54.367 回答