함수 호출에서 C# ReadLine()을 다음 줄로 진행
문제
내 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
{
}
}