char (s) 직렬화 및 역 직렬화

오메르 파룩 졸루

내 수업에 문자 목록이 있습니다. 직렬화 및 역 직렬화는 예상대로 작동합니다. 내 목록에 바이트 순서 표시를 설명하는 데 필요한 문자가 포함되어 있으면. 예제 char 코드는 56256입니다. 그래서이 질문은 아래와 같이 간단한 테스트를 생성했습니다.

[Test]
public void Utf8CharSerializeAndDeserializeShouldEqual()
{
    UInt16 charCode = 56256;
    char utfChar = (char)charCode;
    using (MemoryStream ms = new MemoryStream())
    {
        using (StreamWriter writer = new StreamWriter(ms, Encoding.UTF8, 1024, true))
        {
            var serializer = new JsonSerializer();
            serializer.Serialize(writer, utfChar);
        }

        ms.Position = 0;
        using (StreamReader reader = new StreamReader(ms, true))
        {
            using (JsonTextReader jsonReader = new JsonTextReader(reader))
            { 
                var serializer = new JsonSerializer();
                char deserializedChar = serializer.Deserialize<char>(jsonReader);

                Console.WriteLine($"{(int)utfChar}, {(int)deserializedChar}");
                Assert.AreEqual(utfChar, deserializedChar);
                Assert.AreEqual((int)utfChar, (int)deserializedChar);
            }
        }
    }
}

BOM에 char 코드가 필요하지 않은 경우 테스트가 정상적으로 작동합니다. 예를 들어 65 (A)는이 테스트를 통과합니다.

dbc

귀하의 문제는 Json.NET과 관련이 없습니다. 귀하의 문제가있다 U+DBC0(십진수 56256)이 에 설명 된대로, 잘못된 유니 코드 문자이며, 문서Encoding.UTF8에 의해 사용하여 StreamWriter이러한 문자를 인코딩하지 않습니다 :

Encoding.UTF8UTF8Encoding대체 대체를 사용하여 인코딩 할 수없는 각 문자열과 디코딩 할 수없는 각 바이트를 물음표 ( "?") 문자로 바꾸는 객체를 반환합니다 .

바꿀 경우이를 확인하려면 Encoding.UTF8함께 new UTF8Encoding(true, true)테스트 예제에서 다음과 같은 예외를 얻을 것이다 :

EncoderFallbackException: Unable to translate Unicode character \uDBC0 at index 1 to specified code page. 

유효하지 않은 유니 코드 char을 직렬화 하려면 다음을 사용하여 바이트 배열과 같이 수동으로 인코딩해야합니다.

public static partial class TextExtensions
{
    static void ToBytesWithoutEncoding(char c, out byte lower, out byte upper)
    {
        var u = (uint)c;
        lower = unchecked((byte)u);
        upper = unchecked((byte)(u >> 8));
    }

    public static byte[] ToByteArrayWithoutEncoding(this char c)
    {
        byte lower, upper;
        ToBytesWithoutEncoding(c, out lower, out upper);
        return new byte[] { lower, upper };
    }

    public static byte[] ToByteArrayWithoutEncoding(this ICollection<char> list)
    {
        if (list == null)
            return null;
        var bytes = new byte[checked(list.Count * 2)];
        int to = 0;
        foreach (var c in list)
        {
            ToBytesWithoutEncoding(c, out bytes[to], out bytes[to + 1]);
            to += 2;
        }
        return bytes;
    }

    public static char ToCharWithoutEncoding(this byte[] bytes)
    {
        return bytes.ToCharWithoutEncoding(0);
    }

    public static char ToCharWithoutEncoding(this byte[] bytes, int position)
    {
        if (bytes == null)
            return default(char);
        char c = default(char);
        if (position < bytes.Length)
            c += (char)bytes[position];
        if (position + 1 < bytes.Length)
            c += (char)((uint)bytes[position + 1] << 8);
        return c;
    }

    public static List<char> ToCharListWithoutEncoding(this byte[] bytes)
    {
        if (bytes == null)
            return null;
        var chars = new List<char>(bytes.Length / 2 + bytes.Length % 2);
        for (int from = 0; from < bytes.Length; from += 2)
        {
            chars.Add(bytes.ToCharWithoutEncoding(from));
        }
        return chars;
    }
}

그런 다음 다음과 같이 테스트 방법을 수정합니다.

    public void Utf8JsonCharSerializeAndDeserializeShouldEqualFixed()
    {
        Utf8JsonCharSerializeAndDeserializeShouldEqualFixed((char)56256);
    }

    public void Utf8JsonCharSerializeAndDeserializeShouldEqualFixed(char utfChar)
    {
        byte[] data;

        using (MemoryStream ms = new MemoryStream())
        {
            using (StreamWriter writer = new StreamWriter(ms, new UTF8Encoding(true, true), 1024))
            {
                var serializer = new JsonSerializer();
                serializer.Serialize(writer, utfChar.ToByteArrayWithoutEncoding());
            }
            data = ms.ToArray();
        }

        using (MemoryStream ms = new MemoryStream(data))
        {
            using (StreamReader reader = new StreamReader(ms, true))
            {
                using (JsonTextReader jsonReader = new JsonTextReader(reader))
                {
                    var serializer = new JsonSerializer();
                    char deserializedChar = serializer.Deserialize<byte[]>(jsonReader).ToCharWithoutEncoding();

                    //Console.WriteLine(string.Format("{0}, {1}", utfChar, deserializedChar));
                    Assert.AreEqual(utfChar, deserializedChar);
                    Assert.AreEqual((int)utfChar, (int)deserializedChar);
                }
            }
        }
    }

또는 List<char>일부 컨테이너 클래스에 속성 이있는 경우 다음 변환기를 만들 수 있습니다.

public class CharListConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(List<char>);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var bytes = serializer.Deserialize<byte[]>(reader);
        return bytes.ToCharListWithoutEncoding();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var list = (ICollection<char>)value;
        var bytes = list.ToByteArrayWithoutEncoding();
        serializer.Serialize(writer, bytes);
    }
}

그리고 다음과 같이 적용하십시오.

public class RootObject
{
    [JsonConverter(typeof(CharListConverter))]
    public List<char> Characters { get; set; }
}

두 경우 모두 Json.NET은 바이트 배열을 Base64로 인코딩합니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

직렬화 및 역 직렬화 람다

분류에서Dev

자식 직렬화 및 역 직렬화

분류에서Dev

Jackson의 다형성 직렬화 / 역 직렬화 및 사용자 지정 직렬화 / 역 직렬화

분류에서Dev

잭슨 사용자 정의 직렬화 및 역 직렬화

분류에서Dev

개체 컬렉션 직렬화 및 역 직렬화

분류에서Dev

Jackson을 사용하여 Lambda 직렬화 및 역 직렬화

분류에서Dev

현재 상태로 양식 직렬화 및 역 직렬화

분류에서Dev

clrmq를 통한 직렬화 및 역 직렬화

분류에서Dev

Java에서 인터페이스 직렬화 및 역 직렬화

분류에서Dev

Jackson : Map <String, Object> 직렬화 및 역 직렬화

분류에서Dev

중첩 클래스 직렬화 및 역 직렬화

분류에서Dev

android- Libgdx 직렬화 및 역 직렬화

분류에서Dev

특성없는 C # JSON 직렬화 및 역 직렬화

분류에서Dev

(수동) 이진 검색 트리 직렬화 및 역 직렬화

분류에서Dev

XML 직렬화 및 역 직렬화 List <string> in C #

분류에서Dev

사전을 이진으로 직렬화 및 역 직렬화

분류에서Dev

XmlRoot 요소가없는 XML 직렬화 및 역 직렬화

분류에서Dev

ServiceStack은 객체로 사전 직렬화 및 역 직렬화

분류에서Dev

C #에서 JSON 파일 역 직렬화 및 직렬화

분류에서Dev

Swift3에서 객체의 직렬화 및 역 직렬화

분류에서Dev

metadata-extractor-dotnet 직렬화 및 역 직렬화

분류에서Dev

GSON 및 역 직렬화 오류

분류에서Dev

오류 Json 역 직렬화 및 목록 <>

분류에서Dev

StackOverflowError : LinkedList 및 ArrayList 역 직렬화

분류에서Dev

StackOverflowError : LinkedList 및 ArrayList 역 직렬화

분류에서Dev

JSON 개체 역 직렬화 및 작업

분류에서Dev

gson 및 개조로 json 역 직렬화

분류에서Dev

역 직렬화 : NullReferenceException

분류에서Dev

C # 역 직렬화

Related 관련 기사

  1. 1

    직렬화 및 역 직렬화 람다

  2. 2

    자식 직렬화 및 역 직렬화

  3. 3

    Jackson의 다형성 직렬화 / 역 직렬화 및 사용자 지정 직렬화 / 역 직렬화

  4. 4

    잭슨 사용자 정의 직렬화 및 역 직렬화

  5. 5

    개체 컬렉션 직렬화 및 역 직렬화

  6. 6

    Jackson을 사용하여 Lambda 직렬화 및 역 직렬화

  7. 7

    현재 상태로 양식 직렬화 및 역 직렬화

  8. 8

    clrmq를 통한 직렬화 및 역 직렬화

  9. 9

    Java에서 인터페이스 직렬화 및 역 직렬화

  10. 10

    Jackson : Map <String, Object> 직렬화 및 역 직렬화

  11. 11

    중첩 클래스 직렬화 및 역 직렬화

  12. 12

    android- Libgdx 직렬화 및 역 직렬화

  13. 13

    특성없는 C # JSON 직렬화 및 역 직렬화

  14. 14

    (수동) 이진 검색 트리 직렬화 및 역 직렬화

  15. 15

    XML 직렬화 및 역 직렬화 List <string> in C #

  16. 16

    사전을 이진으로 직렬화 및 역 직렬화

  17. 17

    XmlRoot 요소가없는 XML 직렬화 및 역 직렬화

  18. 18

    ServiceStack은 객체로 사전 직렬화 및 역 직렬화

  19. 19

    C #에서 JSON 파일 역 직렬화 및 직렬화

  20. 20

    Swift3에서 객체의 직렬화 및 역 직렬화

  21. 21

    metadata-extractor-dotnet 직렬화 및 역 직렬화

  22. 22

    GSON 및 역 직렬화 오류

  23. 23

    오류 Json 역 직렬화 및 목록 <>

  24. 24

    StackOverflowError : LinkedList 및 ArrayList 역 직렬화

  25. 25

    StackOverflowError : LinkedList 및 ArrayList 역 직렬화

  26. 26

    JSON 개체 역 직렬화 및 작업

  27. 27

    gson 및 개조로 json 역 직렬화

  28. 28

    역 직렬화 : NullReferenceException

  29. 29

    C # 역 직렬화

뜨겁다태그

보관