【问题标题】:System out of memory exception large txt file into an array [duplicate]系统内存不足异常大txt文件放入数组[重复]
【发布时间】:2016-05-05 06:44:00
【问题描述】:

以下代码适用于小型 txt 文件,但如果我们有大型 txt 文件,则在 string[] array = File.ReadAllLines("hash.txt"); p>

hash.txt 文件大小为 500 mb

我尝试了一些来自互联网的建议,但没有成功。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
namespace Hash_Parser
{
    internal class Program
    {
        private static List<string> users = new List<string>();
        private static Dictionary<string, int> hash_original = new Dictionary<string, int>();
        private static List<string> hash_found = new List<string>();
        private static List<string> pass = new List<string>();
        private static string hash_path = "split.txt";
        private static void split()
        {
            Console.WriteLine("Splitting...");
            StreamWriter streamWriter = new StreamWriter("user.txt");
            StreamWriter streamWriter2 = new StreamWriter("hash.txt");
            string[] array = File.ReadAllLines(Program.hash_path);
            for (int i = 0; i < array.Length; i++)
            {
                string text = array[i];
                string[] array2 = text.Split(new char[]
               {
                   ':'
               }, 2);
                if (array2.Count<string>() >= 2)
                {
                    streamWriter.WriteLine(array2[0]);
                    streamWriter2.WriteLine(array2[1]);
                }
            }
            streamWriter.Close();
            streamWriter2.Close();
            Console.WriteLine("Saved as user.txt and hash.txt");
        }
        private static void populate()
        {
            Console.WriteLine("Populating lists...");
            Program.users.AddRange(File.ReadAllLines("user.txt"));
            Program.pass.AddRange(File.ReadAllLines("pass.txt"));
            Program.hash_found.AddRange(File.ReadAllLines("found.txt"));
            int num = 0;
            string[] array = File.ReadAllLines("hash.txt");
            for (int i = 0; i < array.Length; i++)
            {
                string key = array[i];
                Program.hash_original.Add(key, num);
                num++;
            }
        }
        private static void seek()
        {
            StreamWriter streamWriter = new StreamWriter("userpass.txt");
            int num = 0;
            int num2 = 100;
            foreach (string current in Program.hash_found)
            {
                if (Program.hash_original.ContainsKey(current))
                {
                    streamWriter.WriteLine(Program.users[Program.hash_original[current]] + ":" + Program.pass[num]);
                }
                num++;
                if (num >= num2)
                {
                    Console.Title = string.Concat(new object[]
                   {
                       "Processed: ",
                       num,
                       " : ",
                       Program.hash_found.Count
                   });
                    num2 += 1000;
                }
            }
            Console.Title = string.Concat(new object[]
           {
               "Processed: ",
               num,
               " : ",
               Program.hash_found.Count
           });
            streamWriter.Close();
        }
        private static void Main(string[] args)
        {
            Console.WriteLine("Split hash /split");
            Console.WriteLine("'split.txt'\n");
            Console.WriteLine("Parse hashes /parse");
            Console.WriteLine("'user.txt' | 'found.txt' | 'hash.txt' | 'pass.txt'");
            string a = Console.ReadLine();
            if (a == "/split")
            {
                Program.split();
            }
            else
            {
                if (a == "/parse")
                {
                    Program.populate();
                    Console.WriteLine("Processing...");
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    Program.seek();
                    stopwatch.Stop();
                    Console.WriteLine("Saved as userpass.txt");
                    Console.WriteLine("Time elapsed: " + stopwatch.Elapsed);
                    Console.ReadKey();
                }
            }
        }
    }
}
感谢您的帮助。

【问题讨论】:

  • 即使你逐行读取文件仍然会出现内存不足异常?
  • 如果有 500MB 会引发此错误,请尝试分块加载它
  • 您也可以一次读取一行文件,处理它,然后将一行写入输出。
  • 为什么不循环遍历文件并一次执行较小的部分?

标签: c# arrays


【解决方案1】:

试试这个代码:

foreach (var line in File.ReadLines(_filePath))
{
    //Don't put "line" into a list or collection.
    //Just make your processing on it.
}

引用文本:只需使用 File.ReadLines,它返回一个 IEnumerable 并且不会一次将所有行加载到内存中。

引用链接:https://stackoverflow.com/a/13416225/3041974

希望对你有帮助。

【讨论】:

  • 工作...非常感谢
【解决方案2】:

请注意 .NET 中的进程限制

http://www.codeproject.com/Articles/483475/Memory-Limits-in-a-NET-Process

例如,32 位系统的物理内存不能超过 4 GB。不用说 2^32 将为您提供一个包含 4.294.967.296 个不同条目的虚拟地址空间,而这正是 4GB 限制的来源。但是即使系统上有 4GB 可用,您的应用程序实际上也只能看到 2GB。为什么?

因为在 32 位系统上,Windows 会分割虚拟地址空间 分成两个相等的部分:一个用于用户模式应用程序,另一个用于 对于内核(系统应用程序)。可以覆盖此行为 通过使用 Windows boot.ini 配置文件中的“/3gb”标志。如果我们这样做 因此,系统会为用户应用程序保留 3GB,并为用户应用程序保留 1GB 对于内核。

任务管理器中的进程MEM Usage是什么?

【讨论】:

    猜你喜欢
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多