Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#使用从FileStream创建的StreamWriter覆盖文件_C#_File - Fatal编程技术网

C#使用从FileStream创建的StreamWriter覆盖文件

C#使用从FileStream创建的StreamWriter覆盖文件,c#,file,C#,File,我需要操纵文件的内容: FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); StreamReader sr = new StreamReader(fs); StreamWriter sw = new StreamWriter(fs); newString = someStringTransformation

我需要操纵文件的内容:

 FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);               
 StreamReader sr = new StreamReader(fs);
 StreamWriter sw = new StreamWriter(fs);
 newString = someStringTransformation(sr.ReadToEnd());
 sw.Write(newString);
 fs.flush();
 fs.Close();
但是,上面附加了新闻字符串,而不是用新的更改覆盖文件。需要这样做,以便在读写之间没有其他应用程序可以访问该文件,这就是为什么我要从FileStream对象创建读写器


我知道您可以创建一个StreenWriter,第二个参数设置为false,如前所述。但是,在如上所述创建StreamWriter时,这似乎不是参数之一。

您遇到的问题是,从流中读取数据会前进到文件末尾。然后将追加进一步的写入

这将实现完全覆盖

using(FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
    StreamReader sr = new StreamReader(fs);
    using (StreamWriter sw = new StreamWriter(fs))
    {
        newString = someStringTransformation(sr.ReadToEnd());

        // discard the contents of the file by setting the length to 0
        fs.SetLength(0); 

        // write the new content
        sw.Write(newString);
    }
}

为什么要使用
SetLength
?您的新内容可能比现有字符串短!您最不希望看到的是文件末尾的旧内容。

这里有几个步骤需要执行,但让我明确我的假设:

在整个操作过程中,您需要保持文件处于打开和锁定状态,以防止其他人在此期间访问该文件

话虽如此,以下是您需要做的:

  • 您需要使用
    StreamReader
    阅读内容,正如您所做的那样
  • 您需要将底层流重新定位回起始位置,它的位置已通过读卡器读取而更改
  • 您需要通过
    StreamWriter
    写出转换后的内容,正如您所做的那样
  • 由于下一步,您需要刷新写入程序
  • 您需要将底层流/文件截断到其当前位置,以处理缩短内容的转换
  • 所有这些的代码可能类似于以下程序:


    您可以做的是重新定位流,并删除缓冲数据,以确保没有任何东西阻挡。以你为例:

    FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);               
     StreamReader sr = new StreamReader(fs);
     StreamWriter sw = new StreamWriter(fs);
     newString = someStringTransformation(sr.ReadToEnd());
    
        sr.Position = 0;
        sr.DiscardBufferedData(); 
    
        sw.Position = 0;
    
     sw.Write(newString);
     fs.flush();
     fs.Close();
    
    如果新数据少于旧数据,则需要截断其余数据。使用
    sw.SetLength(newString.Length)

    通过使用Linq,您可以避免这些低级
    及其
    读卡器
    /
    写卡器


    尝试刷新流并将其重新定位到文件的开头,然后写入,然后刷新写入程序,然后截断文件。另一种方法是创建另一个临时文件,将所有新内容保存到该文件,然后删除旧文件并重命名新文件。您尝试的操作毫无意义,您无法防止另一个进程在打开文件前一微秒读取文件。旁注:使用
    IDisposable
    (例如
    FileStream
    )时,使用(FileStream fs=new FileStream..{…}
    将其包装到
    中比调用
    Close
    更好(异常时可能会出现资源泄漏)不要忘记关闭
    StreamWriter
    StreamReader
    。或者可以使用(){}
    块将它们封装在
    中。
    
    FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);               
     StreamReader sr = new StreamReader(fs);
     StreamWriter sw = new StreamWriter(fs);
     newString = someStringTransformation(sr.ReadToEnd());
    
        sr.Position = 0;
        sr.DiscardBufferedData(); 
    
        sw.Position = 0;
    
     sw.Write(newString);
     fs.flush();
     fs.Close();
    
      File.WriteAllText(filePath, someStringTransformation(File.ReadAllText(filePath)));