[英]C# move to end of file with StreamWriter created from FileStream
[英]C# Overwriting file with StreamWriter created from FileStream
我需要操作文件的內容:
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();
但是,上面附加了 newString 而不是用新更改覆蓋文件。 它需要完成,以便沒有其他應用程序可以在讀取寫入之間訪問該文件,這就是我從 FileStream object 創建讀取器和寫入器的原因。
我知道您可以創建一個將第二個參數設置為 false 的 StreanWriter,如此處所述。 但是,當如上所述創建 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
寫出轉換后的內容,就像您所做的那樣所有這些的代碼看起來像這個LINQPad程序:
void Main()
{
const string filePath = @"d:\temp\test.txt";
var encoding = Encoding.UTF8;
using (var stream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
using (var reader = new StreamReader(stream, encoding))
using (var writer = new StreamWriter(stream, encoding))
{
// Read
var contents = reader.ReadToEnd();
// Transform
var transformedContents = contents.Substring(0, Math.Max(0, contents.Length - 1));
// Write out transformed contents from the start of the file
stream.Position = 0;
writer.Write(transformedContents);
writer.Flush();
// Truncate
stream.SetLength(stream.Position);
}
}
只需使用:
FileStream fs = System.IO.File.Create(filePath);
File.Create 將創建或覆蓋文件並返回文件流。
您可以使用Linq避免這些低級Stream
及其Reader
/ Writer
:
File.WriteAllText(filePath, someStringTransformation(File.ReadAllText(filePath)));
您可以做的是重新定位流並刪除緩沖數據以確保沒有任何障礙。 以你的例子為例:
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);
.
也許它會幫助一個。
只需使用FileMode.Open
或FileMode.Truncate
覆蓋文件:
namespace System.IO
{
//
// Summary:
// Specifies how the operating system should open a file.
[ComVisible(true)]
public enum FileMode
{
...
//
// Summary:
// Specifies that the operating system should create a new file. If the file already
// exists, it will be overwritten. This requires System.Security.Permissions.FileIOPermissionAccess.Write
// permission. FileMode.Create is equivalent to requesting that if the file does
// not exist, use System.IO.FileMode.CreateNew; otherwise, use System.IO.FileMode.Truncate.
// If the file already exists but is a hidden file, an System.UnauthorizedAccessException
// exception is thrown.
Create = 2,
//
...
}
或者
namespace System.IO
{
//
// Summary:
// Specifies how the operating system should open a file.
[ComVisible(true)]
public enum FileMode
{
...
//
// Summary:
// Specifies that the operating system should open an existing file. When the file
// is opened, it should be truncated so that its size is zero bytes. This requires
// System.Security.Permissions.FileIOPermissionAccess.Write permission. Attempts
// to read from a file opened with FileMode.Truncate cause an System.ArgumentException
// exception.
Truncate = 5,
...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.