2014-07-08 2 views
0

난과 같이, 두 가지 방법에 .json 파일에서 읽어 노력하고 있어요 :두 가지 방법으로 같은 스트림을 StreamReader하는 방법?

void mainMethod() 
{ 
    Stream theFile = Assembly.GetExecutingAssembly().GetManifestResourcesStream("pathToFile"); 

    Method1(theFile); 

    Method2(theFile); 

} 

void Method1(Stream file) 
{ 
    using (StreamReader fileUsage_1 = new StreamReader(file)) 
    { 
     //do stuff with file 
    } 
} 

void Method2(Stream file) 
{ 
    using (StreamReader fileUsage_2 = new StreamReader(file)) 
    { 
     //do stuff with file 
    } 
} 

mainMethod() 실행하면 예외를 제공합니다 : Method2()Stream was not readable. 나는 문제가 Method2()theFile시를 읽는 것을 믿습니다 그것은 Method1()에서 아직도 사용되고있다. using 블록이 자동으로 파일을 닫은 것 같습니다. theFileMethod1()Method2()에 "중복"하지 않도록 사용자 정의하는 방법을 사용자 정의 할 수 있습니까?

+0

(버퍼 데이터를 폐기에 대한 자세한 내용은 Here로 이동 가능). –

+0

@HansPassant 그래서 어떻게 해결할 수 있습니까? – user3772119

+0

그냥 GetManifestResourcesStream()을 다시 호출하면됩니다. 또는 * leaveOpen * 인수와 함께 StreamReader 생성자를 사용합니다. –

답변

0

다시 읽는 경우 전체 스트림하는 것이 가능하다 :

  1. 스트림이 시크입니다 (stream.CanSeek == true)
  2. 독자는

당신은 일반적으로 1 여부를 제어 할 수 없습니다 닫지 스트림을 할 수 있지만, 필요한 경우 전체 srteam을 검색 가능한 것으로 복사 할 수 있습니다 (예 : Stream.Copy ~ MemoryStream 사용).

독자가 스트림을 닫지 않게하려면 - 스트림의 소유권을 갖지 않는 생성자를 사용하고 다시 사용하면 스트림을 닫지 않습니다. 나는. StreamReader(...,bool leaveOpen). 방금 점에서 Method2로 스트림을 읽는 계속해야하는 경우

마지막으로 다른 독자 (시작 자주) 시작하는 데 필요로하는 곳에 Stream.Position = 0;

노트

  • 처럼 뭔가 위치로 스트림을 모색 할 필요가 Method1을 남겨두면 검색 할 필요가 없습니다. 독자가 스트림을 닫지 않도록하십시오.
  • 다른 방법으로 명시 적으로 독자를 닫을 수는 없지만 (using/.Close 전화 걸기) 그런 코드는 틀리게 보일 것이며 using을 추가하여 수정하면 제대로 작동하지 않습니다.
+0

주십시오. 어떤 코드를 넣어야하는지 지정하십시오. – user3772119

+0

@ user3772119 이미 다른 답변에는 합리적인 샘플이 있습니다. –

0

앞에서 설명한대로 Stream.Position을 설정하십시오. 이렇게 설정하십시오 :

file.Seek (System.IO.SeekOrigin.Begin);

또한 StreamReader의 Using 블록은 종료 할 때 기본 스트림을 닫습니다. File.ReadAllText 메서드를 사용하여 단일 호출로 파일의 열기, 읽기 및 닫기 (삭제)를 수행 할 수 있습니다.

string jsonString = File.ReadAllText (filePath);

+0

어디에서 스트림 위치를 설정합니까? 파일을 사용하기 전에 두 메소드의'using' 블록에서? – user3772119

2

StreamReader를 한 번 열고 각 방법에서 위치를 설정하십시오. 이런 식으로 메소드를 호출하는 순서가 고정되어 있지 않습니다. StreamReader를 처음 열면 기본적으로 위치가 시작으로 설정되므로 Seek (0, SeekOrigin.Begin)에 대한 첫 번째 호출은 중복되지만 향후 호출 순서가 상호 교환 될 수 있습니다.

void mainMethod() 
    { 
     Stream theFile = Assembly.GetExecutingAssembly().GetManifestResourcesStream("pathToFile"); 
     using (StreamReader fileUsage = new StreamReader(theFile)) 
     { 
      Method1(fileUsage); 
      Method2(fileUsage); 
     } 
    } 

    private static void Method1(StreamReader fileUsage) 
    { 
     if (fileUsage != null && fileUsage.BaseStream.CanSeek && fileUsage.BaseStream.CanRead) 
     { 
      fileUsage.BaseStream.Seek(0, SeekOrigin.Begin); 
      fileUsage.DiscardBufferedData(); 
      Console.WriteLine(fileUsage.ReadLine()); 
     } 
    } 
+0

의도는 스트림의 첫 번째 행을 읽기만하는 것이 아니라면'StreamReader.ReadToEnd()'를 제안합니다. – NickSuperb

+0

@ 닉 동의합니다. 필자는 실제로 의도 된 용도가 확실하지 않기 때문에 ReadLine을 일부 데이터를 읽는 예제로 사용했습니다. –

1

내게 전화 해주세요 ...하지만 사용법을 사용하지 않고 간단하게 기본 프로그램으로 추상화 할 수 없습니까? 그렇게. 원하는 경우 위치 재설정을 포함하도록 수정되었습니다.귀하의 방법 항목()가 바로에서는 StreamReader뿐만 아니라 "theFile"스트림을하지 폐쇄

namespace ConsoleApplication12 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      Stream theFile = Assembly.GetExecutingAssembly().GetManifestResourceStream("ConsoleApplication12.test.txt"); 
      using (StreamReader fileUsage_1 = new StreamReader(theFile)) 
      { 
       Method1(fileUsage_1); 
       ResetPosition(theFile, fileUsage_1); // If needed 
       Method2(fileUsage_1); 
      } 

      Console.ReadLine(); 
     } 

     private static void Method2(StreamReader fileUsage) 
     { 
      var test = fileUsage.ReadLine(); 
     } 

     private static void Method1(StreamReader fileUsage) 
     { 
      var test = fileUsage.ReadLine(); 
     } 

     private static void ResetPosition(Stream s, StreamReader sr) 
     { 
      s.Position = 0; 
      sr.DiscardBufferedData(); 
     } 
    } 
} 
+0

+1. 참고 : 스트림에 BOM이있는 경우이 코드가 실패해야한다고 생각합니다. –

+1

BOM으로 인코딩 된 UTF8 파일로 테스트하여 정상적으로 작동하는 것으로 보입니다. – PaulBinder

관련 문제