我在下面包含的代码成功写入CSV文件。但是,如果我写的CSV文件碰巧在Excel中打开,我会得到一个System.IO.Exception
,表示"该文件正由另一个进程使用。"
如何更改代码以便程序继续运行并等到CSV不再在Excel中打开?
private void timer1_Tick(object sender, EventArgs e)
{
int actmonth, actyear, actsecond;
System.DateTime fecha = System.DateTime.Now;
actmonth = fecha.Month;
actyear = fecha.Year;
if (actmonth <= 9)
{
valorfechaact = System.Convert.ToString(actyear) + "00" + System.Convert.ToString(actmonth);
}
else
{
valorfechaact = System.Convert.ToString(actyear) + "0" + System.Convert.ToString(actmonth);
}
actsecond = fecha.Second;
string label;
label = label1.Text;
string at = "@";
string filename = valorfechaact + ".csv";
string ruta3 = System.IO.Path.Combine(at, label, filename);
if (Directory.Exists(label1.Text))
{
StreamWriter wr = new StreamWriter(ruta3, true);
wr.WriteLine("1asd" + actsecond);
wr.Close();
wr.Dispose();
}
else
{
System.Console.WriteLine("no se puede escribir en el archivo");
timer1.Stop();
}
}
答案 0 :(得分:1)
你可以看看这个问题:
https://github.com/liady/webpack-node-externals
讨论的方法之一是简单地尝试访问该文件。如果抛出异常,您可以等待再试一次。
如果您真的想等到工作簿可写,那么您可以这样做,例如通过使用while循环(可能你想要添加一个超时,或者如果相关提醒用户他/她需要在Excel中关闭文件)。 在代码中它可能是这样的:
int someLargeNumberOfIterations = 100000000;
while(FileIsLocked(filepath) && elapsedMs < timeoutMs) {
Thread.SpinWait(someLargeNumberOfIterations);
// Set elapsed
}
// Write the file
其中FileIsLocked是您根据上述帖子编写的函数,timeoutMs是一些适当的超时。
答案 1 :(得分:1)
您可以编写一个Methode,尝试使用FileStream打开File并返回一个布尔标志
可能的解决方案是
public static class FileInfoExtension
{
public static bool IsLocked(this FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
stream?.Close();
}
return false;
}
}
然后你可以使用它
var fileInfo = new FileInfo(ruta3);
if (!fileInfo.IsLocked())
{
// do code
}
一个非常简单(和糟糕)的等待解决方案是
while (file.IsLocked())
{
Thread.Sleep(100);
}
一般是您的代码不清楚且难以阅读。
你有很多的还原代码,很少有变量被命名。 也许这个Guidline可以帮助你https://github.com/dennisdoomen/CSharpGuidelines
可能有一个更清晰的解决方案
private void timer1_Tick(object sender, EventArgs e)
{
var directory = label1.Text;
if (!Directory.Exists(directory))
{
Console.WriteLine("no se puede escribir en el archivo");
timer1.Stop();
return;
}
var now = DateTime.Now;
_valorfechaact = now.Month <= 9 ? $"{now.Year}00{now.Month}" : $"{now.Year}0{now.Month}";
var fullname = Path.Combine("@", directory, $"{_valorfechaact}.csv");
var fileInfo = new FileInfo(fullname);
if (fileInfo.IsLocked())
{
Console.WriteLine($"The File {fullname} is locked!");
return;
}
using (var wr = new StreamWriter(fullname, true))
{
wr.WriteLine("1asd" + now.Second);
}
}