【问题标题】:Writing a large string to file将大字符串写入文件
【发布时间】:2017-09-09 05:17:17
【问题描述】:

我一直在尝试使用以下方法将很长的十六进制字符串(价值 8mb 或 1600 万个字符)写入文件:

File.WriteAllBytes(path, hexarray);

如果我尝试编译我会得到一个错误:

逻辑内存不足

将此十六进制写入文件而不引发错误的最佳方法是什么?

我正在考虑将字符串分成多个字符串,然后在 EOF 处添加 hex1 然后 hex2 但在尝试之前我意识到我仍然会在内存中添加很多字符串。

编辑我应该多指定我的代码

string z = "2412341A4D2341341234141";  <--this is alot longer tho

File.WriteAllBytes("C:/user/asdf/setup.sdf"), StringToByteArray(z));

public static byte[] StringToByteArray(string hex)
    {
        return Enumerable.Range(0, hex.Length)
                         .Where(x => x % 2 == 0)
                         .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                         .ToArray();
    }

【问题讨论】:

  • 你从哪里得到字符串?它是在内存中还是生成的还是您正在复制文件?
  • 十六进制来自我复制十六进制并将其制成字符串的文件
  • 您是在尝试写入字节还是字符?永远不要使用二进制数据中的字符串。一个 c# 字符是两个字节,具有一个私有属性,指示该字符是一个字节还是两个字节。所以 8 mb 字符介于 8 mb 和 16 mb 字节之间。所以你必须使用 Encoding.XXX.GetBytes() 将字符串转换为字节数组。如果您有二进制数据,请不要使用编码转换为字符串。使用 BinaryWriter() 插入二进制数据。
  • @jdweng:在很多情况下,您需要以文本形式表示二进制数据,通常是十六进制或 base64。在这两种情况下,您都不会使用Encoding.GetBytes,也不需要BinaryWriter。目前尚不清楚 OP 的数据实际来自何处——我们不知道此处是否需要十六进制部分——但肯定有一些情况。
  • @Ragekillen:在应用程序中包含文件内容的更好方法是使其成为嵌入式资源文件。

标签: c# arrays byte


【解决方案1】:

考虑查看FileStream 并在可以提供帮助的情况下将完整的数据集保留在内存之外。如果您从一个文件读取并写入另一个文件,则流将提供一种缓冲方式,无需将每个文件全部加载到内存中。

【讨论】:

    【解决方案2】:

    您的问题的标题具有误导性:您收到编译器错误。这与写入文件无关。 可能编译器无法处理源代码中的字符串,因为它太长了。考虑将它存储在一个文本文件中,并从您的代码中读取它......如果需要,您可以将该文件包含在您的资源中。处理后,您可以使用以下技术之一将其写入新文件。

    【讨论】:

      【解决方案3】:

      已回答。正确的做法是将文件添加为资源,然后使用

      将它们提取到目录
      File.WriteAllBytes(path, System.Properties.Resources.core);
      

      感谢@jonskeet 指出这一点

      这不是我最初想要的,但结果相同

      【讨论】:

      • 这没有回答原始问题。答案在 Johan 的回答中 stackoverflow.com/a/46127767 在资源中包含可执行文件是非常低效的,FWIW。通常最好将它们作为不同的文件包含在可执行文件旁边。
      【解决方案4】:

      尝试以下:

                  string hex = "0123456789ABCDEF";
                  string z = "2412341A4D23413412341419";
      
                  List<byte> resutls = new List<byte>();
      
                  for (int i = 0; i < z.Length; i += 2)
                  {
                      byte data = (byte)((hex.IndexOf(z.Substring(i, 1)) << 4) + hex.IndexOf(z.Substring(i + 1, 1)));
                      resutls.Add(data);
                  }
      

      【讨论】:

      • 这将导致问题中报告的相同编译错误。字符串字面量太大。
      • 大卫:你做了一个错误的假设。 Linq 将使用直接 for 循环更多的内存。因此,当 linq 失败时,我的代码将起作用。
      • 这是一个编译时错误......代码无关紧要。它永远不会执行,因为它不会编译。它是字符串文字的大小。
      • 或者你是否成功编译了带有大测试字符串的代码?
      • 为什么要编译一个大字符串?输入通常来自不同的来源。编译大字符串没有任何意义。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-29
      • 1970-01-01
      • 2011-10-24
      • 2016-02-03
      • 2019-09-04
      • 1970-01-01
      相关资源
      最近更新 更多