С# — FileStream: и блокировать файл, и в то же время иметь возможность читать его без усечения и записывать с усечением.

Я полагаю, что мой заголовок не так ясен.

попробую объяснить:

Я могу писать и читать файл с помощью 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();
}

Таким образом, содержимое файла заменяется, но не блокируется файлы.

Но я хочу обоих. Каково решение?


person pikachu    schedule 27.11.2011    source источник
comment
Обрезать с помощью FileStream.SetLength()   -  person Hans Passant    schedule 28.11.2011


Ответы (2)


В вашем первом примере вам нужно сбросить поток, прежде чем писать в него, чтобы заменить содержимое файла, а не добавлять к нему:

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();
}
person Oded    schedule 27.11.2011
comment
Нет, я не думаю, что это хороший способ сделать это. То, что вы предлагаете, насколько я тестировал, работало как режим вставки в текстовых редакторах. Если мой предыдущий текст был намного длиннее, то будут перезаписаны только первые символы. Например, файл содержит ОООООООООО, и я пишу в файл III в своей программе, файл будет содержать IIIIOOOOO. - person pikachu; 28.11.2011
comment
@pikachu - вам нужно использовать SetLength на FileStream, чтобы обрезать его. Ответ обновлен, предполагая UTF8. - person Oded; 28.11.2011

Если вы обрежете поток до 0, он также будет работать, и не нужно будет вычислять новый размер файла в байтах.

fs.Seek(0,0);
fs.SetLength(0);
person Victor Lee    schedule 23.10.2017