2015-06-26 3 views
0

У меня есть текстовый файл, содержащий несколько сообщений JSON. Нет разделителя, кроме новой строки. У меня есть метод, который будет принимать строку JSON и десериализовать ее для некоторого типа объекта.Прочитать текстовый файл с несколькими сообщениями JSON

Как я могу прочитать текстовый файл и перебрать каждую строку Json, чтобы его можно было десериализовать?

Ниже приведен метод десериализации:

public static T JsonDeserialize<T>(string jsonString) 
{ 
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); 
    MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); 
    T obj = (T)ser.ReadObject(ms); 
    return obj; 
} 

ответ

1

Единственное, что я могу придумать, - это прокрутить каждый символ и подсчитать скобки. Когда количество скобок равно нулю, оно добавит объединенную строку в список. В конце вы получите список отдельных строк JSON.

public List<string> GetJsonItems() 
{ 
    int BracketCount = 0; 
    string ExampleJSON = new StreamReader(@"c:\Json.txt").ReadToEnd(); 
    List<string> JsonItems = new List<string>(); 
    StringBuilder Json = new StringBuilder(); 

    foreach (char c in ExampleJSON) 
    { 
     if (c == '{') 
      ++BracketCount; 
     else if (c == '}') 
      --BracketCount; 
     Json.Append(c); 

     if (BracketCount == 0 && c != ' ') 
     { 
      JsonItems.Add(Json.ToString()); 
      Json = new StringBuilder(); 

     } 
    } 
    return JsonItems;  
} 

EDIT: Изменен код для использования StringBuilder и его намного быстрее. Почти мгновенно проанализировал файл JSON объемом 2 МБ.

0

Я рекомендую использовать StreamReader класс. У этого метода есть метод ReadLine(), который вернет вам json сообщений по одному. Вы можете либо вызвать функцию JsonDeserialize при чтении файла, либо поместить все сообщения в список и десериализовать их позже.

List<MyClass> deserializedObjects = new List<MyClass>(); 
using(var reader = new StreamReader(pathToFile)){ 
    while(!reader.EndOfStream){ 
     deserializedObjects.Add(JsonDeserialize<MyClass>(reader.ReadLine())); 
    } 
} 
0

Вы также можете разделить свой текстовый файл и выполнить итерацию через каждую часть JSON.

Что-то вроде этого:

void ReadJsonWithLinebreaks(string jsonFilePath) 
{ 
     string jsonFileContent = File.ReadAllText(jsonFilePath); 
     string[] jsonContentSplitted = jsonFileContent.Split(Environment.NewLine.ToCharArray()); 

     // ... iterate through array that contains your JSON content 
} 

Edit: Использование File.ReadAllLines() вместо File.ReadAllText если ваш JSON-файл поставляется с переносами.

1

если ваши строки JSon отделены друг от друга новых линий вы можете перебрать все строки и разбор их с помощью следующего кода:

List<YourClass> objects = new List<YourClass>(); 
String[] lines = File.ReadAllLines("path\to\file.txt"); 
foreach (string line in lines) 
{ 
    try 
    { 
     var obj = JsonDeserialize<YourClass>(line); 
     objects.Add(obj); 
    } 
    catch (Exception) { } 
} 

Если это не поможет, пожалуйста, напишите образец файл.

+0

Eating exeptions является _very_ плохо, на мой взгляд. –

+0

В зависимости от ваших потребностей. Но это всего лишь быстрый фрагмент, и я не знаю, что должен делать автор, если неудача десериализации. Таким образом, этот код является подсказкой для решения, а не кодом, который он должен скопировать и вставить. –

1

Вы можете использовать jsonReader.SupportMultipleContent Недвижимость.
Не имеет значения разделение между сообщениями новой строки (строк), вкладок или пробелов.

SupportMultipleContent устанавливает значение true/false (по умолчанию false), указывающее, можно ли считывать несколько частей содержимого JSON из непрерывного потока без ошибок.

Пример:

public static void Main() 
{ 
    string json = @" 
    { 
     'Name': 'foo', 
     'Id': 123 
    }{ 
     'Name': 'bar', 
     'Id': 456 
    } 

    //more new line 
    { 
     'Name': 'jar', 
     'Id': 789 
    } 
    "; 

    var persons = DeserializeObjects<Person>(json).ToList(); 
    Console.WriteLine(persons.Count()); 
    foreach (var person in persons) 
    { 
     Console.WriteLine("id: {0}, Name: {1}",person.Id, person.Name); 
    } 

}

static IEnumerable<T> DeserializeObjects<T>(string input) 
    { 
     JsonSerializer serializer = new JsonSerializer(); 
     using (var strreader = new StringReader(input)) 
     using (var jsonreader = new JsonTextReader(strreader)) 
     { 
       //you should use this line 
       jsonreader.SupportMultipleContent = true; 
       while (jsonreader.Read()) 
       {      
        yield return serializer.Deserialize<T>(jsonreader); 
       } 

     } 
    } 


    class Person 
    { 
     public int Id {get;set;} 
     public string Name {get;set;} 
    } 

Try it online

выход:

ID: 123, Имя: Foo

ID: 456, имя: бар

ID: 789, Имя: баночка

Смежные вопросы