C# - FileStream:既锁定文件,又能够在不截断文件的情况下读取文件并在截断文件的情况下写入文件

发布于 2024-12-18 12:26:49 字数 1061 浏览 0 评论 0原文

我想我的标题不太清楚。

我将尝试解释:

我可以使用 FileStream 写入和读取文件,

FileStream fs = new FileStream("C:\\Users\\Public\\text.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);

private void button1_Click(object sender, EventArgs e)
{
    fs.Seek(0,0);
    StreamReader sr = new StreamReader(fs);
    textbox.Text = sr.ReadToEnd();
}

private void button2_Click(object sender, EventArgs e)
{
    StreamWriter sw = new StreamWriter(fs);
    sw.Write(textbox.Text);
    sw.Flush();
}

这样其他程序就无法使用该文件,但我也无法删除内容。写入它只会添加字符串,不会替换内容。

或者我可以在没有 FileStream 的情况下完成此操作:

private void button1_Click(object sender, EventArgs e)
{
    StreamReader sr = new StreamReader("C:\\Users\\Public\\text.txt");
    textBox1.Text = sr.ReadToEnd();
    sr.Close();
}

private void button2_Click(object sender, EventArgs e)
{
    StreamWriter sw = new StreamWriter("C:\\Users\\Public\\text.txt", false);
    sw.Write(textBox1.Text);
    sw.Close();
}

这样,文件的内容被替换,但它对文件没有锁定。

但我两个都想要。解决办法是什么?

I suppose my title isn't that clear.

I'll try to explain:

I can write and read a file using a FileStream

FileStream fs = new FileStream("C:\\Users\\Public\\text.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);

private void button1_Click(object sender, EventArgs e)
{
    fs.Seek(0,0);
    StreamReader sr = new StreamReader(fs);
    textbox.Text = sr.ReadToEnd();
}

private void button2_Click(object sender, EventArgs e)
{
    StreamWriter sw = new StreamWriter(fs);
    sw.Write(textbox.Text);
    sw.Flush();
}

This way other programs can't use the file, but I also can't delete content. Writing to it only adds the string, it doesn't replace the content.

Or I can do it without a FileStream:

private void button1_Click(object sender, EventArgs e)
{
    StreamReader sr = new StreamReader("C:\\Users\\Public\\text.txt");
    textBox1.Text = sr.ReadToEnd();
    sr.Close();
}

private void button2_Click(object sender, EventArgs e)
{
    StreamWriter sw = new StreamWriter("C:\\Users\\Public\\text.txt", false);
    sw.Write(textBox1.Text);
    sw.Close();
}

This way, the content of the file is replaced, but it has no lock on the files.

But I want both. What is the solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冧九 2024-12-25 12:26:49

在第一个示例中,您需要在写入流之前重置流,以便替换文件内容,而不是附加到它:

private void button2_Click(object sender, EventArgs e)
{
    fs.Seek(0,0);
    fs.SetLength(Encoding.UTF8.GetBytes(textbox.Text).Length));
    StreamWriter sw = new StreamWriter(fs);
    sw.Write(textbox.Text);
    sw.Flush();
}

In your first example, you need to reset the stream before you write to it in order to replace the file contents, instead of appending to it:

private void button2_Click(object sender, EventArgs e)
{
    fs.Seek(0,0);
    fs.SetLength(Encoding.UTF8.GetBytes(textbox.Text).Length));
    StreamWriter sw = new StreamWriter(fs);
    sw.Write(textbox.Text);
    sw.Flush();
}
半边脸i 2024-12-25 12:26:49

如果将流截断为 0,它也将起作用,并且无需计算新文件大小(以字节为单位)。

fs.Seek(0,0);
fs.SetLength(0);

If you truncate the stream down to 0, it will also work and no need to calculate the new file size in bytes.

fs.Seek(0,0);
fs.SetLength(0);
幻想少年梦 2024-12-25 12:26:49

如果你想覆盖文件内容,你需要做两件事:

  1. 将EndOfFile设置为0,
  2. 将文件大小设置为0。

如果你使用FileStream FileMode.Truncate,它将通过仅调用一个系统函数将分配大小和eof设置为0 。
从 procMon (SysInteranls) 看到:
operationSeqence_Truncate

如果您使用 FileStream FileMode.OpenOrCreate(或 Open)并使用 fs.Seek(0, 0) + fs.SetLength(0) 或仅 fs.SetLength(0),它将通过调用现在两个系统函数来执行相同的操作。
从 procMon (SysInteranls) 看到:

我倾向于使用第一种方式 代码清晰,没有额外的函数被调用。我们设置模式,仅此而已。

using (var fileStream = new FileStream(path, FileMode.Truncate, FileAccess.Write, FileShare.Read))
using (var binaryWriter = new BinaryWriter(fileStream, Encoding.Unicode))
{
  binaryWriter.Write(bytes, 0, bytes.Length);
}

If you want overwrite content of file, you need to do two things:

  1. set EndOfFile to 0,
  2. set Size of file to 0.

If you use FileStream FileMode.Truncate, it will set allocation size and eof to 0 by call only one system function.
See from procMon (SysInteranls):
operationSeqence_Truncate

If you use FileStream FileMode.OpenOrCreate (or Open) and using fs.Seek(0,0) + fs.SetLength(0) or only fs.SetLength(0), it will do the same by calling now two system functions.
See from procMon (SysInteranls):
operationSeqence-SetLengthWithSeekOrOnlySetLength

I prefare to use the first way. Code is clear and no additional function is calling. We set mode and nothing else.

using (var fileStream = new FileStream(path, FileMode.Truncate, FileAccess.Write, FileShare.Read))
using (var binaryWriter = new BinaryWriter(fileStream, Encoding.Unicode))
{
  binaryWriter.Write(bytes, 0, bytes.Length);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文