Я пытался выяснить, как лучше хранить и извлекать данные из файла, содержащего Json, используя JSon.net. Во время моих исследований я нашел пару способов.
Может ли любой из этих методов использоваться с Json.Net? Есть ли реальная реализация, доступная для статьи в DrDoobs? Я не мог понять метод HandleToken (reader.TokenType, reader.Value).
Текущая статистика:
Около 5 минут, чтобы написать Json размером ~ 60 Мб
Около 3 минут, чтобы прочитать Json.
Текущий код:
public static T DeserializeJsonFromStream<T>(Stream s)
{
using (StreamReader reader = new StreamReader(s))
{
using (JsonTextReader jsonReader = new JsonTextReader(reader))
{
JsonSerializer ser = new JsonSerializer();
ser.Formatting = Newtonsoft.Json.Formatting.None;
ser.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
ser.TypeNameHandling = TypeNameHandling.All;
ser.NullValueHandling = NullValueHandling.Ignore;
ser.Error += ReportJsonErrors;
ser.DateFormatHandling = DateFormatHandling.IsoDateFormat;
return ser.Deserialize<T>(jsonReader);
}
}
}
public static void SerializeJsonIntoStream(object value, Stream s)
{
using (StreamWriter writer = new StreamWriter(s))
{
using (JsonTextWriter jsonWriter = new JsonTextWriter(writer))
{
JsonSerializer ser = new JsonSerializer();
ser.Formatting = Newtonsoft.Json.Formatting.None;
ser.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
ser.TypeNameHandling = TypeNameHandling.All;
ser.NullValueHandling = NullValueHandling.Ignore;
ser.Error += ReportJsonErrors;
ser.Serialize(jsonWriter, value);
jsonWriter.Flush();
}
}
}
Поскольку мне не нужно было считывать сериализованный файл вручную, использование протокола Buffer разрешило проблему. Для сериализации/десериализации одного и того же объема данных требуется 6 секунд.
Он доступен в Nuget по адресу: http://www.nuget.org/packages/protobuf-net
public static async Task<T> DeserializeFromBinary<T>(string filename, StorageFolder storageFolder)
{
try
{
var file = await storageFolder.GetFileAsync(filename);
if (file != null)
{
var stream = await file.OpenStreamForReadAsync();
T content = Serializer.Deserialize<T>(stream);
return content;
}
}
catch (NullReferenceException nullException)
{
logger.LogError("Exception happened while de-serializing input object, Error: " + nullException.Message);
}
catch (FileNotFoundException fileNotFound)
{
logger.LogError("Exception happened while de-serializing input object, Error: " + fileNotFound.Message);
}
catch (Exception e)
{
logger.LogError("Exception happened while de-serializing input object, Error: " + e.Message, e.ToString());
}
return default(T);
}
public static async Task<bool> SerializeIntoBinary<T>(string fileName, StorageFolder destinationFolder, Content content)
{
bool shouldRetry = true;
while (shouldRetry)
{
try
{
StorageFile file = await destinationFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (var stream = await file.OpenStreamForWriteAsync())
{
Serializer.Serialize(stream, content);
shouldRetry = false;
return true;
}
}
catch (UnauthorizedAccessException unAuthorizedAccess)
{
logger.LogError("UnauthorizedAccessException happened while serializing input object, will wait for 5 seconds, Error: " + unAuthorizedAccess.Message);
shouldRetry = true;
}
catch (NullReferenceException nullException)
{
shouldRetry = false;
logger.LogError("Exception happened while serializing input object, Error: " + nullException.Message);
}
catch (Exception e)
{
shouldRetry = false;
logger.LogError("Exception happened while serializing input object, Error: " + e.Message, e.ToString());
}
if (shouldRetry)
await Task.Delay(5000);
}
return false;
}