C# using子句是否会关闭此流?
我显然已经养成了一个坏的编码习惯。下面是我一直在编写的代码示例:C# using子句是否会关闭此流?,c#,filestream,dispose,streamreader,C#,Filestream,Dispose,Streamreader,我显然已经养成了一个坏的编码习惯。下面是我一直在编写的代码示例: 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子句在Str
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
子句在StreamReader
上显式调用了Close()
和Dispose()
,所以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
?还是我弄错了
编辑
我决定发布一段真正有问题的代码,看看我们是否能找到问题的根源。我现在只是好奇
我想我在使用
子句时遇到了问题,所以我扩展了所有内容,但每次都无法复制。我在这个方法调用中创建了这个文件,所以我认为其他任何东西都没有打开该文件的句柄。我还验证了从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);
}
private静态void generateFile(列出信用)
{
账户一;
string creditFile=Path.Combine(Settings.CreditLocalPath,DateTime.Now.ToString(“MMddyy hhmmss”)+“.credits”);
StreamWriter creditsFile=新建StreamWriter(File.Open(creditFile,FileMode.Create));
creditsFile.WriteLine(“代码\公司”);
foreach(学分c中的学分)
{
if(DataAccessLayer.AccountExists(i))
{
字符串tpsAuth=DataAccessLayer.GetAuthCode(i.Pin);
creditsFile.WriteLine(String.Format(“{0}{1}\t{2:0.00}”,i.AuthCode,i.Pin,c.CreditAmount));
}
其他的
{
c、 错误=真;
c、 ErrorMessage=“无账户”;
}
DataAccessLayer.AddCredit(c);
}
creditsFile.Close();
creditsFile.Dispose();
字符串dest=Path.Combine(Settings.CreditArchivePath,Path.GetFileName(creditFile));
文件移动(creditFile,dest);
//文件。删除(错误文件);
}
是,StreamReader.Dispose
关闭底层流(对于所有创建流的公共方式)。但是,还有一个更好的选择:
using (TextReader reader = File.OpenText("file.txt"))
{
}
这还有一个额外的好处,即它打开底层流,并向Windows提示您将按顺序访问它
这里有一个测试应用程序,它显示了第一个版本对我有效。我不想说这是什么特别的证据,但我很想知道它对你有多有效
using System;
using System.IO;
class Program
{
public static void Main(string[] args)
{
for (int i=0; i < 1000; i++)
{
using(StreamReader sr = new StreamReader
(File.Open("somefile.txt", FileMode.Open)))
{
Console.WriteLine(sr.ReadLine());
}
File.Move("somefile.txt", "somefile.bak");
File.Move("somefile.bak", "somefile.txt");
}
}
}
注意-您的使用块不需要嵌套在它们自己的块中-它们可以是连续的,如:
using(FileStream fs = File.Open("somefile.txt", FileMode.Open))
using(StreamReader sr = new StreamReader(fs))
{
//read file
}
这种情况下的处理顺序仍然与嵌套块相同(即,在这种情况下,StreamReader仍将在FileStream之前进行处理)。是否有可能其他文件锁定了somefile.txt 从本地(到文件)cmd行的简单检查 如果其他东西有锁的话,可能会给你一些线索
或者,您可以获取更多详细信息,并检查您的应用程序是否正常发布。我会尝试使用
FileInfo.Open()
和FileInfo.MoveTo()
而不是File.Open()
和File.Move(
)。您还可以尝试使用FileInfo.OpenText()
。但这些只是建议。因为这似乎不是一个编码问题,我将戴上我的syadmin帽子并提供一些建议
编辑:如果您可以在服务器机器的act中捕获它,那么Sysinternal的句柄将告诉您它打开了什么 知道我为什么不能在第一个区块移动文件吗?不,应该没问题。奇怪。第一个版本总是失败,第二个版本总是有效吗?刚刚尝试了第一个版本,在一个循环中对我有效了20次。我用第一种方式编码了100次,以前从来没有出现过问题。现在,我正在windows共享上打开该文件,这是解决该问题的唯一方法。第一个例子每次都失败了,第二个例子每次都成功了。所以我认为我做得不对。有没有可能其他应用程序打开并锁定了该文件?你也可以检查一下。
DateTime.Now.ToString(“MMddyy hhmmss”)
你每秒创建多少个文件?@Dave,每天一个。此函数一天只调用一次。请检查防病毒扫描程序、索引服务器等。我认为,从另一个角度看,它看起来更好。请理解,这与任何其他具有初始子句、后跟语句的构造(其中语句可以是块)没有什么不同。(一个典型的例子是if(list!=null)foreach(列表中的对象项){…}
,它是嵌套在if
中的foreach
),具体来说,这是“嵌套”——也是一种非理想的缩进样式,因为它不指示嵌套。如果缩进除第一行以外的所有行,则会更清楚发生了什么:第二个“使用”嵌套在第一行中。我将尝试FileInfo方法,但我认为在下面,它们只是对File.MoveYep的调用,但可能它们在内部处理流(由FileInfo.Open()创建)。另外,文档中说他们只做了一次安全检查,所以可能会稍微快一点……非常有趣。我过去在另一个没有编写代码的应用程序中也遇到过问题,但我们发现罪魁祸首是AVG。我必须对此进行调查。
using(FileStream fs = File.Open("somefile.txt", FileMode.Open))
using(StreamReader sr = new StreamReader(fs))
{
//read file
}
net files