문제

나는 분명히 나 자신을 나쁜 코딩 습관으로 일했다. 다음은 내가 작성한 코드의 예입니다.

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()StreamReaderFileStream 폐쇄 될 것입니다.

내가 가진 문제를 해결할 수있는 유일한 방법은 위의 블록을 이것으로 바꾸는 것입니다.

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);
}
도움이 되었습니까?

해결책

예, 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");
        }
    }
}

그것이 효과가 있다면, 그것은 당신이 읽는 동안하는 일과 관련이 있다는 것을 암시합니다 ...

그리고 이제 편집 된 질문 코드의 단축 버전이 있습니다. 네트워크 공유에서도 다시 잘 작동합니다. 내가 바꾸 었다는 점에 유의하십시오 FileMode.Create 에게 FileMode.CreateNew - 그렇지 않으면 ~할 수 있었다 여전히 기존 파일의 손잡이가있는 앱이었습니다. 이것이 당신을 위해 효과가 있습니까?

using System;
using System.IO;

public class Test
{    
    static void Main()
    {
        StreamWriter creditsFile = new StreamWriter(File.Open("test.txt", 
                                          FileMode.CreateNew));

        creditsFile.WriteLine("code\\inc");

        creditsFile.Close();
        creditsFile.Dispose();

        File.Move("test.txt", "test2.txt");
    }
}

다른 팁

참고 - 사용 블록을 자체 블록에 중첩 할 필요는 없습니다.

using(FileStream fs = File.Open("somefile.txt", FileMode.Open))
using(StreamReader sr = new StreamReader(fs))
{
    //read file
}

이 경우 폐기 순서는 여전히 중첩 블록과 동일합니다 (즉, Streamreader는이 경우 필사자 전에 여전히 폐기합니다).

나는 사용하려고 노력할 것이다 FileInfo.Open() 그리고 FileInfo.MoveTo() 대신에 File.Open() 그리고 File.Move(). 당신은 또한 사용하려고 노력할 수 있습니다 FileInfo.OpenText(). 그러나 이것들은 단지 제안입니다.

다른 것이 somefile.txt에 잠금 장치가있을 가능성이 있습니까?

로컬 (파일)에서 간단한 확인 CMD 라인

net files

다른 것에 자물쇠가 있으면 단서를 줄 수 있습니다.

또는 당신은 같은 것을 얻을 수 있습니다 필라몬 자세한 내용을 보려면 앱이 제대로 공개되는지 확인하십시오.

이것은 코딩 문제가 아닌 것 같아서 Syadmin 모자를 착용하고 몇 가지 제안을 제공 할 것입니다.

  1. 파일이 생성 된대로 파일을 스캔하는 클라이언트 또는 서버의 바이러스 스캐너.
  2. 기회주의 잠금 네트워크 공유에 문제를 해결하는 습관이 있습니다. 플랫 파일 데이터베이스가있는 여러 읽기/쓰기 클라이언트의 문제라는 사실을 알지만 캐싱 확실히 당신의 문제를 설명 할 수 있습니다.
  3. 파일 열기 캐시. 이것이 Win2K에서 여전히 문제인지 아닌지 확실하지 않지만 Filemon이 당신에게 말할 것입니다.

편집 : 서버 시스템에서 ACT에서 잡을 수 있다면 Sysinternal의 손잡이가 열린 내용을 알려줍니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top