Microsoft MVP성태의 닷넷 이야기
.NET Framework: 350. String 데이터를 Stream으로 변환하는 방법 [링크 복사], [링크+제목 복사],
조회: 25143
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)

String 데이터를 Stream으로 변환하는 방법

사실 이게 하나의 글로 씌여지기에는 좀 단순한 문제이긴 합니다. ^^

검색만 해보면 다음과 같은 식으로 2가지 방법이 나오는데요.

// 방법 1: Encoding 타입 사용
string test = "ab";

byte[] byteArray = Encoding.UTF8.GetBytes(test);
MemoryStream stream1 = new MemoryStream(byteArray);

// 방법 2: StreamWriter 사용
MemoryStream stream2 = new MemoryStream();
StreamWriter sw = new StreamWriter(stream2, Encoding.UTF8);
sw.Write(test);
sw.Flush();
stream2.Position = 0;

그런데, 전자와 후자는 결과가 틀립니다. 실제로 한번 출력을 해볼까요? ^^

foreach (byte aByte in stream1.ToArray())
{
    Console.Write(aByte.ToString("x") + ", ");
}

Console.WriteLine();

foreach (byte aByte in stream2.ToArray())
{
    Console.Write(aByte.ToString("x") + ", ");
}

// 출력 결과
61, 62,
ef, bb, bf, 61, 62,

보시는 것처럼 StreamWriter는 3바이트가 더 출력됩니다. 이게 뭔지 혹시 감이 오세요? ^^ 그렇습니다. StreamWriter는 BOM(Byte Order Mark)을 함께 출력합니다.

보통 이것이 문제가 되지 않을 수 있지만, BOM 인식을 간과하는 특정 클래스가 있다면 상황이 달라집니다. 바로 DataContractJsonSerializer가 그 예입니다. 예를 들어, 아래와 같이 stream을 건네주면,

public class Test
{
    public string id { get; set; }
}

string test = "{ \"id\": \"ab\" }";

MemoryStream stream2 = ...[BOM을 쓰는 방식]...;

DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(Test));
Test user2 = dcjs.ReadObject(stream2) as Test;

BOM 데이터를 해석하려고 시도하는 바람에 "System.Runtime.Serialization.SerializationException" 예외가 발생합니다.

System.Runtime.Serialization.SerializationException was unhandled
  HResult=-2146233076
  Message=There was an error deserializing the object of type ConsoleApplication1.Test. Encountered unexpected character 'i'.
  Source=System.Runtime.Serialization
  StackTrace:
       at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
       at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(XmlDictionaryReader reader)
       at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(Stream stream)
       at ConsoleApplication1.Program.Main(String[] args) in d:\...\Program.cs:line 45
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
		...[생략]...
  InnerException: System.Xml.XmlException
       HResult=-2146232000
       Message=Encountered unexpected character 'i'.
       Source=System.Runtime.Serialization
       LineNumber=0
       LinePosition=0
       StackTrace:
            at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, XmlException exception)
            at System.Runtime.Serialization.Json.XmlJsonReader.ReadAttributes()
            ...[생략]...
            at System.Runtime.Serialization.XmlObjectSerializer.InternalReadObject(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
            at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
       InnerException: 

물론, "Encoding.UTF8.GetBytes"를 이용하여 BOM을 제거한 stream을 넘겨주면 오류가 발생하지 않습니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 10/28/2024]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2014-06-11 03시56분
[김영준] 인코딩 설정시 BOM을 설정을 지정할 수도 있습니다. ^^

bool isBOM = false;
StreamWriter sw = new StreamWriter(stream2, new UTF8Encoding(isBOM) );
[guest]
2014-06-11 11시52분
@김영준 좋은 의견 감사드립니다. ^^
정성태

... 121  122  123  124  125  126  127  128  129  130  131  132  133  134  [135]  ...
NoWriterDateCnt.TitleFile(s)
1710정성태7/8/201431387개발 환경 구성: 230. 유니코드의 Surrogate Pair, Supplementary Characters가 뭘까요?파일 다운로드2
1709정성태7/8/201428019VS.NET IDE: 91. Visual Studio에서 32/64비트 IIS Express 실행하는 방법
1708정성태7/7/201425376VS.NET IDE: 90. Visual Studio - 사용자 정의 정적 분석 규칙 만드는 방법 [3]파일 다운로드1
1707정성태7/4/201423526.NET Framework: 449. C#에서 C++로 VARIANT 넘겨주는 방법파일 다운로드1
1706정성태7/3/201421933.NET Framework: 448. .NET SmartClient 컨트롤을 윈도우 8/2012에서 활성화하는 방법파일 다운로드1
1705정성태7/2/201436431VC++: 78. 보이어-무어(Boyer-Moore) 알고리즘이 정말 빠를까? [6]파일 다운로드1
1704정성태7/2/201422861.NET Framework: 447. w3wp.exe AppPool 재생(recycle)하는 방법 정리
1703정성태7/2/201423634.NET Framework: 446. Assembly.Load를 이용해 GAC에 등록된 어셈블리를 로드하는 방법 [1]파일 다운로드1
1702정성태6/23/201423461Phone: 11. Xamarin.Forms - 2. XAML을 이용한 페이지 개발파일 다운로드1
1701정성태6/23/201435709개발 환경 구성: 229. .NET Reflector + Reflexil 도구를 이용해 DLL 코드 변경 [4]
1700정성태6/23/201422399VS.NET IDE: 89. Visual Studio에서 기본 제공되는 성능 프로파일 [2]
1699정성태6/22/201424686Phone: 10. Xamarin.Forms - 1. Forms 시작하기 [2]파일 다운로드1
1698정성태6/22/201426553.NET Framework: 445. [부연 설명] 쉬운 C# 코드를 어럽게 이해하기 [2]
1697정성태6/22/201422231VS.NET IDE: 88. Visual Studio에서 직접 컴파일하는 IL 언어 확장 도구 - IL Support
1696정성태6/22/201421663.NET Framework: 444. clojure와 C#을 통해 이해하는 Sequence와 Vector 형식의 차이점 [1]
1695정성태6/21/201420742개발 환경 구성: 228. PowerShell ISE에서 (입력 기능이 있는) 콘솔 응용 프로그램을 시작하는 방법
1694정성태6/21/201422362개발 환경 구성: 227. 닷넷 용 ClojureCLR 개발환경 설정
1693정성태6/20/201422870개발 환경 구성: 226. Clojure 언어의 윈도우 개발환경 설정
1692정성태6/19/201433284오류 유형: 231. Visual Studio 2013 한글 버전 설치 오류 - The form specified for the subject is not one supported or known by the specified trust provider
1691정성태6/18/201428677개발 환경 구성: 225. 유닉스 계열의 tail 명령어가 제공되는 PowerShell [1]
1690정성태6/18/201431407개발 환경 구성: 224. DirectShow 예제 구하는 방법 [3]
1689정성태6/18/201428343오류 유형: 230. C++ 가변 인자 사용시 va_start 파라미터 전달 방법 [2]
1688정성태6/15/201421173오류 유형: 229. 갤럭시 노트 3 환경에서 Xamarin 앱 배포 충돌
1687정성태6/15/201427694개발 환경 구성: 223. PowerShell로 Visual Studio 빌드 스크립트 작성파일 다운로드1
1686정성태6/12/201425806Windows: 96. 윈도우 8 - 그림 암호를 이용해 로그인 시 지연 현상을 해결하는 방법 [1]
1685정성태6/10/201432313.NET Framework: 443. 자바 8과 C#의 람다(Lambda) 지원에 대한 비교 [12]
... 121  122  123  124  125  126  127  128  129  130  131  132  133  134  [135]  ...