Я, очевидно, выработал у меня плохую привычку кодирования. Вот пример кода, который я писал:
using(StreamReader sr = new StreamReader(File.Open("somefile.txt", FileMode.Open)))
{
//read file
}
File.Move("somefile.txt", "somefile.bak"); //can't move, get exception that I the file is open
Я подумал, что поскольку в предложении using
явно указаны Close()
и Dispose()
на StreamReader
, то FileStream
также будет закрыт.
Единственный способ решить проблему, с которой я столкнулся, - это изменить приведенный выше блок следующим образом:
using(FileStream fs = File.Open("somefile.txt", FileMode.Open))
{
using(StreamReader sr = new StreamReader(fs))
{
//read file
}
}
File.Move("somefile.txt", "somefile.bak"); // can move file with no errors
Должно ли закрытие StreamReader
путем размещения в первом блоке также закрыть базовый FileStream
? Или я ошибся?
Редактировать
Я решил опубликовать фактический оскорбительный блок кода, чтобы посмотреть, сможем ли мы добраться до сути этого. Мне просто любопытно сейчас.
Я думал, что у меня есть проблема в предложении using
, поэтому я расширил все, и он все еще не может копировать каждый раз. Я создаю файл в этом вызове метода, поэтому я не думаю, что что-то еще имеет открытый дескриптор файла. Я также проверил правильность строк, возвращаемых из вызовов Path.Combine
.
private static void GenerateFiles(List<Credit> credits)
{
Account i;
string creditFile = Path.Combine(Settings.CreditLocalPath, DateTime.Now.ToString("MMddyy-hhmmss") + ".credits");
StreamWriter creditsFile = new StreamWriter(File.Open(creditFile, FileMode.Create));
creditsFile.WriteLine("code\inc");
foreach (Credit c in credits)
{
if (DataAccessLayer.AccountExists(i))
{
string tpsAuth = DataAccessLayer.GetAuthCode(i.Pin);
creditsFile.WriteLine(String.Format("{0}{1}\t{2:0.00}", i.AuthCode, i.Pin, c.CreditAmount));
}
else
{
c.Error = true;
c.ErrorMessage = "NO ACCOUNT";
}
DataAccessLayer.AddCredit(c);
}
creditsFile.Close();
creditsFile.Dispose();
string dest = Path.Combine(Settings.CreditArchivePath, Path.GetFileName(creditFile));
File.Move(creditFile,dest);
//File.Delete(errorFile);
}