문제

내 C# 앱에서는 한 줄씩 구분된 7자리 문자열이 포함된 간단한 텍스트 문서를 ReadLine()에 공급하려고 합니다.내가 하려는 것은 함수가 호출될 때마다 다음 7자리 문자열을 가져오는 것입니다.지금까지 내가 가진 것은 다음과 같습니다.

string invoiceNumberFunc()
    {
        string path = @"C:\Users\sam\Documents\GCProg\testReadFile.txt";
        try
        {
            using (StreamReader sr = new StreamReader(path))
            {
                invoiceNumber = sr.ReadLine();

            }

        }
        catch (Exception exp)
        {
            Console.WriteLine("The process failed: {0}", exp.ToString());
        }
       return invoiceNumber;
    }

voiceNumberFunc()가 호출될 때마다 다음 줄로 어떻게 이동합니까?

미리 감사드립니다.

도움이 되었습니까?

해결책

계속 붙잡아야 할 거야 StreamReader 호출 사이에 이를 새 매개변수로 메소드에 전달하거나 클래스의 멤버 변수로 만듭니다.

개인적으로 나는 매개 변수가 되는 아이디어를 선호하므로 멤버 변수로 끝나지 않습니다. 이렇게 하면 수명을 더 쉽게 관리할 수 있습니다.

void DoStuff()
{
    string path = @"C:\Users\sam\Documents\GCProg\testReadFile.txt";
    using (StreamReader sr = new StreamReader(path))
    {
        while (keepGoing) // Whatever logic you have
        {
            string invoice = InvoiceNumberFunc(sr);
            // Use invoice
        }
    }
}

string InvoiceNumberFunc(TextReader reader)
{
    string invoiceNumber;
    try
    {
        invoiceNumber = reader.ReadLine();
    }
    catch (Exception exp)
    {
        Console.WriteLine("The process failed: {0}", exp.ToString());
    }
    return invoiceNumber;
}

다른 팁

함수에서 스트림 리더를 생성하고 처분하기 때문에 할 수 없습니다. 두 가지 방법이 떠 오릅니다.

스트림 리더를 멤버 변수에 저장하거나 한 번에 모두 읽고 멤버 변수에 배열을 저장할 수 있습니다.

또는 반환 유형을 IEnumerable<string>, 그리고, 그리고 부분을 변경합니다 using 블록 :

while ((invoiceNumber = sr.ReadLine()) != null) {
    yield return invoiceNumber;
}

이런 식으로 전화 할 수 있습니다 foreach 너의 invoiceNumberFunc.

새 스트리어 리더를 만드는 대신 동일한 스트리 레이더를 사용해야합니다. 새 제품을 만들고 파일 시작시 바로 다시 시작하는 오래된 것을 처분 할 때마다마다.

스트림에있는 위치에 대한 동일한 streamreader 참조를 전달하거나 필요한 경우 기본 스트림에서 seek ()를 사용하는 위치를 기록하십시오. 나는이 중 첫 번째를 개인적으로 추천합니다.

메소드 내부에서 스트림 리더를 만들지 않고 클래스 레벨에서 만들고 메소드에서 사용한 다음 완료되면 독자를 처리/닫으려면이 작업을 재 작업해야합니다. 같은 것 :

class MyClass
{
    private StreamReader sr;

    string invoiceNumberFunc()
    {
        if (sr == null) 
            sr = new StreamReader(path);

        if (sr.EndOfStream)  {
            sr.Close();
            sr = null;
            return string.Empty;
        }

        try {
            return sr.ReadLine();
        }
        catch(Exception exp) {
            Console.WriteLine("Process failed {0}",exp.ToString());
            return string.Empty;
        }
    }
}

이 경우 수업을 만드는 것이 좋습니다. IDisposable 따라서 Streamreader가 폐기되는지 확인하고 여기에서 수행 한 작업을 수행하고 종료하는 대신 "초기화"/"닫기"루틴을 만들 수 있습니다.

당신이 찾고있는 것은 yield 명령:-

IEnumerable<string> GetInvoiceNumbers()
{
    string path = @"C:\Users\sam\Documents\GCProg\testReadFile.txt";
    using (StreamReader sr = new StreamReader(path))
    {
        while (!sr.EndOfStream)
        {
           yield return sr.ReadLine();
        }
    }
}

이제이 기능의 반환을 각각 간단하게 소비 할 수 있습니다.

foreach(string invoiceNumber in GetInvoiceNumbers())
{
   //Do Stuff with invoice number
}

또는 LINQ로 창의력을 발휘하십시오.

이 작업을 수행하는 다른 방법은 반복자 블록에서 기능을 수익률 반환 명세서

유일한 것은 알몸의 시도 / 캐치에서 수율 반환을 사용할 수 없으므로 시도에 최종 조항을 추가하고 캐치를 제거하는 것입니다. 그래서 당신의 코드는 다음과 같습니다.

    IEnumerable<String> invoiceNumberFunc()
    {
        string path = @"C:\Users\sam\Documents\GCProg\testReadFile.txt";
        try
        {
            using ( System.IO.StreamReader sr = new System.IO.StreamReader( path ) )
            {
                String invoiceNumber;
                while ( ( invoiceNumber = sr.ReadLine() ) != null )
                {
                    yield return sr.ReadLine();
                }
            }
        }
        finally
        {
        }
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top