【问题标题】:ToArray() function limitationToArray() 函数限制
【发布时间】:2017-02-27 07:23:33
【问题描述】:

我正在使用.ToArray() 方法将我的字符串转换为char 数组,其大小我保持char[] buffer = new char[1000000]; 但是当我使用以下代码时:

using (StreamReader streamReader = new StreamReader(path1))
{
    buffer = streamReader.ReadToEnd().ToCharArray();
}
// buffer = result.ToArray();
threadfunc(data_path1);

缓冲区的大小固定为 8190,即使在使用 .ToCharArray().ToArray() 后没有读取整个文件。 .ToCharArray().ToArray() 有大小限制的原因是什么?好像我不使用此函数一样,我能够以字符串格式读取整个文件,但是当尝试使用此函数将其转换为 char 数组时,我遇到了大小限制。

【问题讨论】:

  • 您是否尝试将ReadToEnd()ToCharArray() 的调用分开。 (即将第一个的结果放在 a 字符串中,然后在字符串上调用第二个。)
  • 使用ToCharacterArray 获取字符的方式... 您可以声明数组buffer 而不指定大小,读取时它将调整为正确的大小。换句话说,char[] buffer; 会起作用。
  • ToCharArray() 将整个字符串转换为字节数组。它对生成的数组的大小没有限制。
  • 首先,在覆盖代码之前分配给buffer 的任何内容,因此您分配的1MB 缓冲区只留给垃圾收集器。问题是,文件有多大?

标签: c# arrays toarray


【解决方案1】:

我的猜测是问题是在您调用ToCharArray() 之前应该完成读取。这可能会帮助你。您不需要定义缓冲区,因为 ToCharArray() 会创建 char[] 自身的新实例。

string content;
using (StreamReader streamReader = new StreamReader(path1))
{
    content = streamReader.ReadToEnd();
}
var buffer = content.ToCharArray();

【讨论】:

  • 应该在你调用 ToCharArray 之前完成 - 你的意思是 streamReader.ReadToEnd() 在读取器被处置之前返回“未完成”字符串?
  • Dispose 是一个超集。你可能会打电话给streamReader.Flush() 流有一个坏习惯,即当它们的函数返回时没有完成工作。只是我的经验
【解决方案2】:

ToCharArray() 返回数组的新实例。因此,您的buffer 将引用新实例,即ReadToEnd 返回的数据大小。

如果您想保持buffer 相同的大小,只需将新数组添加到现有数组即可

char[] buffer = new char[1000000];
using (StreamReader streamReader = new StreamReader(path1))
{
    var tempArray = streamReader.ReadToEnd().ToCharArray();
    tempArray.CopyTo(buffer, 0);
}

如果你只想使用结果数组 - 你不需要“预测”数组的大小 - 只需使用返回的一个

public char[] GetArrayFromFile(string pathToFile)
{
    using (StreamReader streamReader = new StreamReader(path1))
    {
        var data = streamReader.ReadToEnd();
    }
    return data.ToCharArray();
}    

var arrayFromFile = GetArrayFromFile(@"..\path.file");

【讨论】:

    【解决方案3】:

    您可能使用了不正确的编码。默认StreamReader(String)使用UTF8编码:

    完整的文件路径由 path 参数指定。这个 构造函数将编码初始化为 UTF8Encoding 和缓冲区 大小为 1024 字节。

    除非您有特殊需要,否则不要预先分配缓冲区大小。

    如果你的文件是 ASCII 格式,你需要更新你的 StreamReader 构造函数:

    char[] buffer = null;
    
    using (StreamReader streamReader = new StreamReader(path1, Encoding.ASCII))
    {
        buffer = streamReader.ReadToEnd().ToCharArray();
    }
    // buffer = result.ToArray();
    threadfunc(data_path1);
    

    【讨论】:

      【解决方案4】:

      您的文件是否包含二进制数据?如果它包含 EOF 字符并且流以文本模式打开(StreamReader 会这样做),则该字符将发出文件结束信号,即使它实际上不是文件结束。

      我可以通过在文本模式下随机读取 .exe 文件来重现这一点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-01
        • 2021-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-07
        • 1970-01-01
        • 2020-03-16
        相关资源
        最近更新 更多