4

생성 된 XML을 서버 디스크에 쓰지 않고 메모리에 보관해야하는 작업을 사용자가 작성했습니다. 여기 MemoryStream이있는 xml의 끝에있는 예기치 않은 "nul"캐랙 터들

내 코드입니다 :

public FileContentResult MyAction() 
{ 
    MemoryStream myStream = new MemoryStream(); 
    XDocument xml = GenerateXml(...); 
    xml.Save(myStream); 
    myStream .Position = 0; 
    return File(myStream.GetBuffer(), "text/xml", "myFile.xml"); 
} 

모든 것이 잘 작동하는 것처럼 보인다는 XML이 올바른지, 나는 파일을 다운로드 할 수 있습니다,하지만 난 끝에 691920 "NUL"caracters을 왜 이해가 안 돼요

enter image description here

그들이에서 온 않습니다 내 파일의 (그 caracters의 수는 XML의 길이에 관련이있는 것으로 보인다)? 어떻게 그들을 제거 할 수 있습니까?

[업데이트]

나는이 시도 :

public FileContentResult MyAction() 
{ 
    XDocument xml = GenerateXml(...); 
    byte[] bytes = new byte[xml.ToString().Length * sizeof(char)]; 
    Buffer.BlockCopy(xml.ToString().ToCharArray(), 0, bytes, 0, bytes.Length); 
    return File(bytes, "text/xml", "myFile.xml"); 
} 

을 그리고는 "NUL"문자를하지 않았다. 그래서 나는 파일 끝에 여분의 캐랙 터를 추가하는 MemoryStream이라고 가정합니다. 내 예제에서 whith 두 번째 코드 내 문제가 해결되었습니다.

하지만 읽을 수없는 Word 문서도 생성합니다 (내용에 문제가 있기 때문에 xxx.docx를 열 수 없습니다). 나는 여기에서도 같은 문제가 있다고 가정한다. 메모리 스트림은 파일 끝에 여분의 캐랙 터를 추가하여 손상시킨다.

답변

9

문제는 myStream.GetBuffer()입니다. GetBuffer() 메서드는 MemoryStream에서 사용하는 기본 배열 배열을 반환하며 실제 데이터를 포함하지 않는 "예비"부분을 포함합니다. 문서에서 :

버퍼에는 사용되지 않은 할당 된 바이트가 들어 있습니다. 예를 들어 문자열 "test"가 MemoryStream 객체에 기록되면 GetBuffer에서 반환 된 버퍼의 길이는 4가 아니라 256이며 사용되지 않은 바이트는 252 바이트입니다. 버퍼의 데이터 만 가져 오려면 ToArray 메서드를 사용합니다. 그러나 ToArray는 데이터 복사본을 메모리에 만듭니다.

대신 GetBuffer()를 사용하는 ToArray()를 사용 - 또는 실제로 사용하는 방법을 버퍼의 많은 알고 스트림의 길이를 사용합니다.

업데이트 된 코드에서 기본적으로 문자열을 UTF-16으로 변환한다는 점에 유의해야합니다. 이는 필요할 크기의 두 배가된다는 것을 의미 할 수 있으며, 주장하는 인코딩을 따르지 않을 수도 있습니다. 나는 그 접근법을 추천하지 않을 것이다.