2016-06-18 9 views
4

구문 분석하기 전에 XML 문서의 인코딩을 검색하려고합니다. 그래서 스택 에서 오버플로이 스크립트를 발견했습니다.C# EndOfStream 항상 true - 0으로 탐색/위치가 작동하지 않음

public static XElement GetXMLFromStream(Stream uploadStream) 
{ 
    /** Remember position */ 
    var position = uploadStream.Position; 

    /** Get encoding */ 
    var xmlReader = new XmlTextReader(uploadStream); 
    xmlReader.MoveToContent(); 

    /** Move to remembered position */ 
    uploadStream.Seek(position, SeekOrigin.Begin); // with "pos" = 0 it not works, too 
    uploadStream.Seek(position, SeekOrigin.Current); // if I remove this I have the same issue! 

    /** Read content with detected encoding */ 
    var streamReader = new StreamReader(uploadStream, xmlReader.Encoding); 
    var streamReaderString = streamReader.ReadToEnd(); 
    return XElement.Parse(streamReaderString); 
} 

하지만 작동하지 않습니다. 항상 얻을 수 EndOfStream사실. 그러나 그것은 !!!!가 아니다! -.-

예를 들어 문자열이 <test></test>입니다. 시작 : 0, 끝 : 13

ReadToEnd 또는 MoveToContent이면 끝까지 성공적으로 처리됩니다. EndOfStream사실입니다. I (예) 0 Seek 또는 Position 통해 위치를 재설정하면

이어서 new StreamReader 방송 항상 EndOfStream 사실이다.

것은 uploadStream은 닫을 수없는 스트림입니다.

http 업로드 스트림의 SharpZipLib 스트림입니다. 따라서이 스트림을 닫을 수는 없습니다. 나는 그걸로 만 일할 수있다.

그리고 PositionSeekPosition에 ... 때문 ReadToEnd 릴레이를 작동뿐만 아니라 때문에 나쁜 일이다. - 그렇지 않으면 효과가있다. 나는 생각한다!

아마 당신은이 상황

가 사전에 대단히 감사 :-) 내를 도울 수 있습니다!

예 : Example of <code>EndOfStream</code> is true - but the Position is not at the end!

+0

Zip 스트림은 분명히 문제를 혼란스럽게합니다. 네트워크 스트림은 검색을 지원하지 않으므로 바이트를 읽으면 다시 검색 할 수 없게됩니다. MemoryStream을 사용하여 직접 버퍼링하지 않는 한. 많은 메모리가 필요할 수 있습니다. 임시 파일에 써야 할 수도 있습니다. –

답변

2

이 방법은 입력 스트림의 일부 유형 근본적으로 호환된다. 스트림은 Seek을 전혀 지원하지 않아도됩니다. 실제로 Stream에는 Seek이 사용 가능한지 여부를 구체적으로 감지하는 속성 인 CanSeek이 있습니다. 코드는 Seek이 실패 할 수 있다는 점을 고려해야합니다.

간단하지만 메모리 효율이 좋지 않은 방법은 스트림 내용을 MemoryStream으로 복사하는 것입니다. 그 중 하나는 Seek을 지원하므로 원하는대로 할 수 있습니다. 사실 ReadToEnd()을 사용한다는 것은 데이터가 너무 커서 메모리 사용으로 인해 문제가 발생하지 않는다는 것을 암시합니다. 따라서이 문제를 해결할 수 있습니다.

참고 : Seek이 지원되지 않으면 NotSupportedException이 표시됩니다. 처리중인 스트림 구현처럼 보이지만 지원되지는 않지만 제대로 구현되지 않았습니다. 적어도 CanSeekfalse을 반환하기를 바랍니다. 그래도이 사실을 계속 신뢰할 수 있습니다.

+0

'CanSeek'은 항상 사실입니다. 그리고 예외는 없습니다. 그래서 내가 여기서 너 한테 묻는다. 어쩌면 SharpZipLib *의 버그일까요? – Patrick

+1

@Patrick 그래, 그게 내가 걱정하고 왜 내 메모를 포함 시켰는지. 구현의 버그처럼 보일 수도 있지만, 해결 방법은 동일합니다. 모든 것을 'MemoryStream'에 복사하면 정상적으로 작동합니다. – hvd

+0

고맙습니다. #hvd 나는 같은 것을 알았고 et voilà - 그것은 작동합니다! – Patrick

1

옵션 1 :

XElement를는 XML 스트림으로부터 직접 판독하는 방법 Load()있다. 내부적으로 인코딩을 관리합니다. 불필요한 문자열을 피하면 더 효율적입니다. 그렇다면 이것을 사용하지 않는 이유는 무엇입니까?

XElement.Load(uploadStream); 

옵션 2 :

당신이 정말로, 문자열 작업 새로운 XmlTextReader는()를 사용 해달라고하십시오. XmlTextReader.Create()에는 다음과 같은 기능이 추가되어 있습니다.

var xmlReader = XmlTextReader.Create(uploadStream); 
var streamReaderString = xmlReader.ReadOuterXml(); 
return XElement.Parse(streamReaderString); 
+1

양호한 호출 인 경우 OP는 "구문 분석하기 전에 XML 문서의 인코딩을 감지하려고합니다."라고 말합니다. 왜 파싱을 제외하고는 인코딩을 사용하지 않는지 설명하지 않습니다. – hvd