Słyszałem, że Json.NET jest szybszy niż DataContractJsonSerializer i chciałem spróbować ...
Ale nie mogłem znaleźć żadnych metod w JsonConvert, które pobierają strumień, a nie ciąg.
Na przykład do deserializacji pliku zawierającego JSON na WinPhone używam następującego kodu, aby wczytać zawartość pliku do ciągu, a następnie deserializować do formatu JSON. Wydaje się, że w moich (bardzo ad-hoc) testach jest około 4 razy wolniejsze niż przy użyciu DataContractJsonSerializer do deserializacji bezpośrednio ze strumienia ...
// DCJS
DataContractJsonSerializer dc = new DataContractJsonSerializer(typeof(Constants));
Constants constants = (Constants)dc.ReadObject(stream);
// JSON.NET
string json = new StreamReader(stream).ReadToEnd();
Constants constants = JsonConvert.DeserializeObject<Constants>(json);
Czy robię to źle?
źródło
Obecna wersja Json.net nie pozwala na użycie zaakceptowanego kodu odpowiedzi. Aktualną alternatywą jest:
Dokumentacja: Deserializacja formatu JSON ze strumienia pliku
źródło
stream.Position = 0;
aby poprawnie zdeserializować mój plik JSON.źródło
JsonSerializer ser = JsonSerializer.Create(settings);
, możesz zdefiniować ustawienia, które mają być używane podczas de / serializacji.Serialize
implementacją jest to, że zamyka onaStream
przekazywany jako argument, co w zależności od aplikacji może stanowić problem. Dzięki .NET 4.5+ możesz uniknąć tego problemu, używającStreamWriter
przeciążenia konstruktora z parametrem,leaveOpen
który pozwala pozostawić otwarty strumień.Napisałem klasę rozszerzenia, aby pomóc mi w deserializacji ze źródeł JSON (ciąg, strumień, plik).
Deserializacja jest teraz tak prosta, jak pisanie:
Mam nadzieję, że pomoże to komuś innemu.
źródło
Using SomeJsonHelpersNamespace
tam, gdzie to konieczne, lub usuńthis
słowo kluczowe i użyjJsonHelpers.CreateFromJsonString(someJsonString)
Pro : jest tak łatwiejszy w użyciu :)Encoding.Default
jest złe, ponieważ będzie zachowywać się inaczej na różnych komputerach (zobacz duże ostrzeżenie w dokumentacji Microsoft). JSON ma być UTF-8 i tego oczekuje JsonSerializer. Tak powinno byćEncoding.UTF8
. Kod taki, jaki jest, będzie generował zniekształcone ciągi lub zakończy się niepowodzeniem w deserializacji, jeśli zostaną użyte znaki inne niż ASCII.Doszedłem do tego pytania, szukając sposobu na przesłanie otwartej listy obiektów na a
System.IO.Stream
i odczytanie ich z drugiego końca, bez buforowania całej listy przed wysłaniem. (W szczególności przesyłam strumieniowo utrwalone obiekty z MongoDB przez interfejs API sieci Web).@Paul Tyng i @Rivers wykonali świetną robotę, odpowiadając na pierwotne pytanie, a ja wykorzystałem ich odpowiedzi, aby stworzyć dowód słuszności mojego problemu. Postanowiłem opublikować tutaj moją aplikację na konsolę testową na wypadek, gdyby ktoś inny miał ten sam problem.
Zauważ, że możesz otrzymać wyjątek, gdy
AnonymousPipeServerStream
zostanie usunięty, zignorowałem to, ponieważ nie ma to związku z problemem.źródło
{"sign in":{"username":"nick"}}{"buy item":{"_id":"32321123"}}
i musi to zobaczyć jako dwa fragmenty JSON sygnalizujące zdarzenie za każdym razem, gdy odczytuje fragment. W nodejs można to zrobić w 3 wierszach kodu.