>

아래에 포함 된 코드는 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();
        }
    }


  • 답변 # 1

    FileStream으로 파일을 열고 부울 플래그를 반환하는 Methode를 작성할 수 있습니다

    가능한 해결책은

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

  • 답변 # 2

    이 질문을 살펴볼 수 있습니다 :

    Excel 통합 문서가 열려 있는지 확인

    논의 된 접근 방법 중 하나는 단순히 파일에 접근을 시도하는 것입니다. 예외가 발생하면 기다렸다가 다시 시도하십시오.

    워크 북이 쓰기 가능한 상태가 될 때까지 정말로 기다리려면 예를 들어 while 루프를 사용하여 (아마 시간 초과를 추가하거나 관련성이있는 경우 사용자가 Excel에서 파일을 닫아야한다고 경고합니다). 코드에서는 다음과 같을 수 있습니다.

    int someLargeNumberOfIterations = 100000000;
    while(FileIsLocked(filepath) && elapsedMs < timeoutMs) {
       Thread.SpinWait(someLargeNumberOfIterations);
       // Set elapsed
    }
    // Write the file
    
    
    여기서 FileIsLocked는 위에서 언급 한 포스트를 기반으로 작성하는 함수이며 timeoutM은 적절한 시간 초과입니다.

  • 이전 Redis 데이터베이스를위한 Hazelcast 대안
  • 다음 php - 이벤트가있는 td 요소 강조