C# 按编号编辑文件中的行

C# 按编号编辑文件中的行,c#,C#,我必须编写一个字符串的实现,将它的值存储在硬盘上,而不是存储在ram上(我知道这听起来有多么愚蠢,但它的目的是教我们如何在ram和硬盘上使用不同的排序算法)。这是我到目前为止写的: class HDDArray : IEnumerable<int> { private string filePath; public int this[int index] { get { using (var reade

我必须编写一个字符串的实现,将它的值存储在硬盘上,而不是存储在ram上(我知道这听起来有多么愚蠢,但它的目的是教我们如何在ram和硬盘上使用不同的排序算法)。这是我到目前为止写的:

class HDDArray : IEnumerable<int>
{
    private string filePath;

    public int this[int index]
    {
        get
        {
            using (var reader = new StreamReader(filePath))
            {
                string line = reader.ReadLine();

                for (int i = 0; i < index; i++)
                {
                    line = reader.ReadLine();
                }

                return Convert.ToInt32(line);
            }
        }
        set
        {
            using (var fs = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                var reader = new StreamReader(fs);
                var writer = new StreamWriter(fs);

                for (int i = 0; i < index; i++)
                {
                    reader.ReadLine();
                }

                writer.WriteLine(value);
                writer.Dispose();
            }
        }
    }

    public int Length
    {
        get
        {
            int length = 0;

            using (var reader = new StreamReader(filePath))
            {
                while (reader.ReadLine() != null)
                {
                    length++;
                }
            }

            return length;
        }
    }

    public HDDArray(string file)
    {
        filePath = file;

        if (File.Exists(file))
            File.WriteAllText(file, String.Empty);
        else
            File.Create(file).Dispose();
    }

    public IEnumerator<int> GetEnumerator()
    {
        using (var reader = new StreamReader(filePath))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                yield return Convert.ToInt32(line);
            }
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
类HDDArray:IEnumerable
{
私有字符串文件路径;
公共int这个[int索引]
{
得到
{
使用(var reader=newstreamreader(filePath))
{
字符串行=reader.ReadLine();
对于(int i=0;i

我面临的问题是,当我试图编辑一行(在索引器的设置部分)时,我最终添加了一个新行,而不是编辑旧行(原因很明显,我只是不知道如何修复它)。

我需要更正,但我不认为有一种简单的方法可以重新编写特定的行,因此,您可能会发现重写文件更容易—修改该行

您可以按如下方式更改设置代码:

  set
  {
    var allLinesInFile = File.ReadAllLines(filepath);
    allLinesInFile[index] = value;
    File.WriteAllLines(filepath, allLinesInFile);
  }

不言而喻,这里应该有一些安全检查来检查文件是否存在以及
索引

我认为,为了完成排序算法的作业,您不必担心内存大小问题

当然,请添加要读取的现有检查文件

注意:示例中的行计数从0开始

string[] lines = File.ReadAllLines(filePath);

using (StreamWriter writer = new StreamWriter(filePath))
{
   for (int currentLineNmb = 0; currentLineNmb < lines.Length; currentLineNmb++ )
   {
       if (currentLineNmb == lineToEditNmb)
       {
          writer.WriteLine(lineToWrite);
          continue;
       }
       writer.WriteLine(lines[currentLineNmb]);                
   }
}
string[]lines=File.ReadAllLines(filePath);
使用(StreamWriter=新StreamWriter(文件路径))
{
对于(int currentLineNmb=0;currentLineNmb
您的数组设计用于处理整数。这样的类很容易创建,因为所有数字的长度都是4字节

class HDDArray : IEnumerable<int>, IDisposable
{
    readonly FileStream stream;
    readonly BinaryWriter writer;
    readonly BinaryReader reader;

    public HDDArray(string file)
    {
        stream = new FileStream(file, FileMode.Create, FileAccess.ReadWrite);
        writer = new BinaryWriter(stream);
        reader = new BinaryReader(stream);
    }

    public int this[int index]
    {
        get
        {
            stream.Position = index * 4;
            return reader.ReadInt32();
        }
        set
        {
            stream.Position = index * 4;
            writer.Write(value);
        }
    }

    public int Length
    {
        get
        {
            return (int)stream.Length / 4;
        }
    }

    public IEnumerator<int> GetEnumerator()
    {
        stream.Position = 0;
        while (reader.PeekChar() != -1)
            yield return reader.ReadInt32();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public void Dispose()
    {
        reader?.Dispose();
        writer?.Dispose();
        stream?.Dispose();
    }
}

当然,如果数据在磁盘上的原因是因为它不适合内存,这将是一个小问题。可以将一个文件流式传输到另一个文件中,然后将新文件重命名为旧文件。很好的一点是@BenVoigt,如果所讨论的文件可能非常大,则写入临时文件将是更好的解决方案。我必须将
Encoding.ASCII
添加到writer和reader中,以避免崩溃。看起来很好,谢谢。
HDDArray arr = new HDDArray("test.dat");

Console.WriteLine("Length: " + arr.Length);

for (int i = 0; i < 10; i++)
    arr[i] = i;

Console.WriteLine("Length: " + arr.Length);

foreach (var n in arr)
    Console.WriteLine(n);

// Console.WriteLine(arr[20]); // Exception!

arr.Dispose(); // release resources