2017-08-22 2 views
-1

Der Code, den ich unten enthalten habe, schreibt erfolgreich in eine CSV-Datei. Aber wenn die CSV-Datei, mit der ich schreibe, in Excel geöffnet ist, erhalte ich eine System.IO.Exception, die anzeigt, dass "die Datei von einem anderen Prozess verwendet wird".Vermeiden Sie "Datei von einem anderen Prozess verwendet" IO-Ausnahme

Wie kann ich meinen Code ändern, damit das Programm weiterläuft und warten, bis die CSV in Excel nicht mehr geöffnet ist?

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(); 
     } 
    } 
+3

helfen Sie die Datei nicht, wenn seine offene innerhalb Excel als Excel wird es sperren überschreiben können. Sie könnten die Datei immer wieder mit einem eindeutigen Namen schreiben, wenn der IO-Fehler auftritt. –

+0

@AlexK. Danke für deine schnelle Antwort, wie kann ich das tun? –

+2

versuchen/fangen bei dieser Ausnahme? –

Antwort

1

Sie können eine Methode schreiben, die die Datei mit einem Filestream zu öffnen versuchen und geben einen booleschen Flag

Eine mögliche Lösung ist

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; 
    } 
} 

Dann können Sie es

verwenden
var fileInfo = new FileInfo(ruta3); 
    if (!fileInfo.IsLocked()) 
    { 
     // do code 
    } 

Eine sehr einfache (und schlechte) Lösung zu warten ist

Allgemein ist Ihr Code unklar und schwer zu lesen.

Sie haben viel Redudant-Code und einige Variablen sind schlecht benannt. Vielleicht Guidline können Sie https://github.com/dennisdoomen/CSharpGuidelines

Vielleicht ein wenig klarer Lösung ist

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); 
     } 
    } 
1

Sie konnten einen Blick auf diese Frage nehmen:

Checking if an Excel Workbook is open

Einer der Ansätze, die diskutiert werden, ist die Datei zu einfach versuchen, zuzugreifen. Wenn dies eine Ausnahme auslöst, können Sie warten und es erneut versuchen.

Wenn Sie wirklich warten möchten, bis die Arbeitsmappe beschreibbar ist, können Sie das tun, z. Verwenden Sie eine while-Schleife (wahrscheinlich möchten Sie eine Zeitüberschreitung hinzufügen oder den Benutzer ggf. warnen, dass er/sie die Datei in Excel schließen muss).

int someLargeNumberOfIterations = 100000000; 

while(FileIsLocked(filepath) && elapsedMs < timeoutMs) { 
    Thread.SpinWait(someLargeNumberOfIterations); 

    // Set elapsed 
} 

// Write the file 

wo FileIsLocked ist eine Funktion, die Sie auf dem oben genannten Beitrag basiert schreiben und timeoutMs ist einige entsprechende Timeout: In Code könnte es so etwas wie sein.

Verwandte Themen