如何使用Stream Writer向文件开头写入内容?

8

我希望将我的字符串插入到文件的开头。但是在流编写器中没有追加函数可以在开头追加。那么我该怎么做呢?

我的代码是:

string path = Directory.GetCurrentDirectory() + "\\test.txt";
StreamReader sreader = new StreamReader(path);
string str = sreader.ReadToEnd();
sreader.Close();

StreamWriter swriter = new StreamWriter(path, false);

swriter.WriteLine("example text");
swriter.WriteLine(str);
swriter.Close();

但看起来它似乎没有进行优化。那么还有其他方法吗?

1
将数据写入文件的开头会覆盖原有内容。考虑将数据追加到文件末尾而不是开头。 - Oded
@0_______0 这就像我所做的一样。 - Hamed
@Oded我害怕覆盖掉.所以我在寻找另一种方法,如果有的话! - Hamed
1
为什么需要写入文件的_start_位置? - Oded
正如你所见,这会导致你在写作时遇到问题。如果这是类似于日志文件的东西,请追加到末尾。 - Oded
显示剩余2条评论
3个回答

10

你已经接近成功:

        string path = Directory.GetCurrentDirectory() + "\\test.txt";
        string str;
        using (StreamReader sreader = new StreamReader(path)) {
            str = sreader.ReadToEnd();
        }

        File.Delete(path);

        using (StreamWriter swriter = new StreamWriter(path, false))
        {
            str = "example text" + Environment.NewLine + str;
            swriter.Write(str);
        }

+1。另外,简单的new StreamWriter(path, true)修复也可以起到作用。 - Alexei Levenkov
代码编辑:移除不必要的.Close()调用 - using已经处理了它。 - Alexei Levenkov
5
答案未考虑文件大小可能超出可用的虚拟内存空间区域。 - SerG

4
如果您不必考虑其他进程向同一文件写入,并且您的进程具有目录创建权限,则处理此问题的最有效方法是:
  1. 使用临时名称创建新文件
  2. 编写新文本
  3. 从文件中追加旧文本
  4. 删除文件
  5. 重命名临时文件
这样做可能不会那么酷和快,但至少您不必为现在使用的方法在内存中分配大量字符串。
然而,如果您确定文件将很小,例如少于几兆字节长,则您的方法并不那么糟糕。
不过,您可以简化代码:
public static void InsertText( string path, string newText )
{
    if (File.Exists(path))
    {
        string oldText = File.ReadAllText(path);
        using (var sw = new StreamWriter(path, false))
        {
            sw.WriteLine(newText);
            sw.WriteLine(oldText);
        }
    }
    else File.WriteAllText(path,newText);
}

对于大文件(即>几MB)

public static void InsertLarge( string path, string newText )
{
    if(!File.Exists(path))
    {
        File.WriteAllText(path,newText);
        return;
    }

    var pathDir = Path.GetDirectoryName(path);
    var tempPath = Path.Combine(pathDir, Guid.NewGuid().ToString("N"));
    using (var stream = new FileStream(tempPath, FileMode.Create, 
        FileAccess.Write, FileShare.None, 4 * 1024 * 1024))
    {
        using (var sw = new StreamWriter(stream))
        {
            sw.WriteLine(newText);
            sw.Flush();
            using (var old = File.OpenRead(path)) old.CopyTo(sw.BaseStream);
        }
    }
    File.Delete(path);
    File.Move(tempPath,path);
}

为什么需要显式创建支持FileStream? - SerG
SerG,那是一段时间以前的事了,但我敢打赌是因为它提供了一个带有缓冲区大小的过载。 - aiodintsov

0

类似这样:

    private void WriteToFile(FileInfo pFile, string pData)
    {
        var fileCopy = pFile.CopyTo(Path.GetTempFileName(), true);

        using (var tempFile = new StreamReader(fileCopy.OpenRead()))
        using (var originalFile = new  StreamWriter(File.Open(pFile.FullName, FileMode.Create)))
        {
            originalFile.Write(pData);
            originalFile.Write(tempFile.ReadToEnd());
            originalFile.Flush();
        }

        fileCopy.Delete();
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接