Возникает ошибка доступа к потоку при его повторном использовании внутри цикла
static void Main(string[] args)
{
string strControl = null;
string str = null;
FileStream fStream = new FileStream("Text.txt", FileMode.OpenOrCreate);
StreamWriter streamWriter= new StreamWriter(fStream);
StreamReader streamReader = new StreamReader(fStream);
//Цикл для опроса пользователя
do
{
Console.WriteLine("Начало цикла");
strControl = Console.ReadLine();
//Выбор между чтением из файла и записью в файл
if (strControl == "чтение")
{
while(streamReader.ReadLine() != null)
{
Console.WriteLine(streamReader.ReadLine());
}
streamReader.Close();
}
else if (strControl == "запись")
{
Console.WriteLine("ID сотрудника: ");
str = Console.ReadLine();
streamWriter.Write(str + " ");
streamWriter.Close();
}
else if (strControl == "выход")
{
break;
}
else
{
Console.WriteLine("Повторите запрос!");
}
} while (strControl != "стоп");
Console.ReadKey();
}
}
}
Ответы (1 шт):
У вас методы streamReader.Close()
и streamWriter.Close()
закрывают поток, а после их закрытия доступ к потоку становится невозможным. Это вызывает проблемы при попытке повторного чтения или записи в файл. Чтобы избежать этой ситуации, используйте using вот еще док - автоматически управляет временем жизни потока и сам закрывает его по завершении работы
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
string strControl = null;
string str = null;
// Создаем и открываем файловый поток
using (FileStream fStream = new FileStream("Text.txt", FileMode.OpenOrCreate))
{
// Создаем объекты для записи и чтения на основе одного и того же файлового потока
using (StreamWriter streamWriter = new StreamWriter(fStream))
using (StreamReader streamReader = new StreamReader(fStream))
{
// Цикл для опроса пользователя
do
{
Console.WriteLine("Начало цикла");
strControl = Console.ReadLine();
// Выбор между чтением из файла и записью в файл
if (strControl == "чтение")
{
// Сброс указателя файла на начало перед чтением
fStream.Seek(0, SeekOrigin.Begin);
string line;
while ((line = streamReader.ReadLine()) != null)
{
Console.WriteLine(line);
}
// Сбрасываем буфер потока
streamReader.DiscardBufferedData();
}
else if (strControl == "запись")
{
Console.WriteLine("ID сотрудника: ");
str = Console.ReadLine();
streamWriter.WriteLine(str);
// Сбрасываем буфер потока, чтобы данные гарантированно записались в файл
streamWriter.Flush();
}
else if (strControl == "выход")
{
break;
}
else
{
Console.WriteLine("Повторите запрос!");
}
} while (strControl != "стоп");
}
}
Console.ReadKey();
}
}
старая версия использвоания using
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
string strControl = null;
string str = null;
FileStream fStream = null;
StreamWriter streamWriter = null;
StreamReader streamReader = null;
try
{
fStream = new FileStream("Text.txt", FileMode.OpenOrCreate);
streamWriter = new StreamWriter(fStream);
streamReader = new StreamReader(fStream);
do
{
Console.WriteLine("Начало цикла");
strControl = Console.ReadLine();
if (strControl == "чтение")
{
fStream.Seek(0, SeekOrigin.Begin);
string line;
while ((line = streamReader.ReadLine()) != null)
{
Console.WriteLine(line);
}
streamReader.DiscardBufferedData();
}
else if (strControl == "запись")
{
Console.WriteLine("ID сотрудника: ");
str = Console.ReadLine();
streamWriter.WriteLine(str);
streamWriter.Flush();
}
else if (strControl == "выход")
{
break;
}
else
{
Console.WriteLine("Повторите запрос!");
}
} while (strControl != "стоп");
}
finally
{
if (streamReader != null) streamReader.Close();
if (streamWriter != null) streamWriter.Close();
if (fStream != null) fStream.Close();
}
Console.ReadKey();
}
}
без использования using
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
string strControl = null;
string str = null;
// Создаем и открываем файловый поток
FileStream fStream = new FileStream("Text.txt", FileMode.OpenOrCreate);
StreamWriter streamWriter = new StreamWriter(fStream);
StreamReader streamReader = new StreamReader(fStream);
try
{
// Цикл для опроса пользователя
do
{
Console.WriteLine("Начало цикла");
strControl = Console.ReadLine();
// Выбор между чтением из файла и записью в файл
if (strControl == "чтение")
{
// Сброс указателя файла на начало перед чтением
fStream.Seek(0, SeekOrigin.Begin);
string line;
while ((line = streamReader.ReadLine()) != null)
{
Console.WriteLine(line);
}
// Сбрасываем буфер потока
streamReader.DiscardBufferedData();
}
else if (strControl == "запись")
{
Console.WriteLine("ID сотрудника: ");
str = Console.ReadLine();
streamWriter.WriteLine(str);
// Сбрасываем буфер потока, чтобы данные гарантированно записались в файл
streamWriter.Flush();
}
else if (strControl == "выход")
{
break;
}
else
{
Console.WriteLine("Повторите запрос!");
}
} while (strControl != "стоп");
}
finally
{
// Закрываем и освобождаем ресурсы вручную
if (streamReader != null)
streamReader.Dispose();
if (streamWriter != null)
streamWriter.Dispose();
if (fStream != null)
fStream.Dispose();
}
Console.ReadKey();
}
}
чтобы обновить версию языка
а) Перейдите на официальный сайт .NET
б) Выберите последнюю версию .NET SDK и скачайте установщик.
в) Запустите установщик и следуйте инструкциям на экране.
После установки вы можете обновить проект, указав в файле .csproj
необходимую версию языка C#
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
так же, обратите внимание, что в вашем коде вы используете один и тот же файловый поток (FileStream) для чтения и записи, что возможно может создать ошибку System.ObjectDisposedException : 'Cannot access a closed file.'
Я предложу использовать отдельные FileStream
для чтения и записи. Для чтения - FileMode.Open
и FileAccess.Read
, а для записи — FileMode.Append
и FileAccess.Write
. Мне кажется, что такой подход разделяет потоки для одной конкретной операции
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
string strControl = null;
string str = null;
// Цикл для опроса пользователя
do
{
Console.WriteLine("Начало цикла");
strControl = Console.ReadLine();
if (strControl == "чтение")
{
// Создаем поток только для чтения
using (FileStream fStream = new FileStream("Text.txt", FileMode.Open, FileAccess.Read))
using (StreamReader streamReader = new StreamReader(fStream))
{
string line;
while ((line = streamReader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
else if (strControl == "запись")
{
// Создаем поток только для записи
using (FileStream fStream = new FileStream("Text.txt", FileMode.Append, FileAccess.Write))
using (StreamWriter streamWriter = new StreamWriter(fStream))
{
Console.WriteLine("ID сотрудника: ");
str = Console.ReadLine();
streamWriter.WriteLine(str);
}
}
else if (strControl == "выход")
{
break;
}
else
{
Console.WriteLine("Повторите запрос!");
}
} while (strControl != "стоп");
Console.ReadKey();
}
}
Я тестировала не на русском, потому что консоль у меня не выдает кирилицу, но вы поймете думаю, что файл успешно записался и прочитался
Début du cycle // начало
écriture // я ввела команду написать
ID de l'employé :
25 // какое то Id
Début du cycle
écriture // еще ввожу запись
ID de l'employé :
35 // еще какой-то сотрудник
Début du cycle
écriture // для больше уверенности добавим еще запись
ID de l'employé :
88 // хорошее число, почему бы и да
Début du cycle
lecture // мы читаем файл с записью
25
35
88
Début du cycle
// затем я ввела команду выход в моем случае sortie и программа завершилась успешно