2013-08-16 5 views
0

У меня есть ~ 7Mb текстовый файл, который нужно извлечь некоторую информацию и содержит много примеров подобного формата в:Получение определенной информации из текстового файла

  "name": "Riki's Dagger", 
      "defindex": 0, 
      "item_class": "dota_item_wearable", 
      "item_type_name": "#DOTA_WearableType_Daggers", 
      "item_name": "#DOTA_Item_Rikis_Dagger", 
      "proper_name": false, 
      "item_quality": 0, 
      "image_inventory": null, 
      "min_ilevel": 1, 
      "max_ilevel": 1, 
      "image_url": "", 
      "image_url_large": "", 

Я хочу, чтобы извлечь имя и defindex, убедитесь, что этот экземпляр имеет/не содержит некоторых ключевых слов, а затем помещает его в новый текстовый файл, чтобы потом использовать его. Мой план состоял в том, чтобы искать файл для каждого экземпляра «name» (с кавычками) и устанавливать все содержимое перед следующим экземпляром «name» для переменной с именем current. Затем оттуда найдите текущую строку для необходимой мне информации. Это лучший способ сделать это и как я буду заниматься этим? Должен ли я использовать Regex или слишком большой файл? Некоторое направление будет высоко оценено.

Это то, что я до сих пор:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Data; 
using System.IO; 

namespace ConsoleApplication1 
{ 
    class Test 
    { 
     static void Main(string[] args) 
      { 
      string ingameschemaFilePath = @"C:\Users\Andrew\Documents\GitHub\SteamBot\Bin\Debug\ingameschema.txt"; 
      string dota2schemaFilePath = @"C:\Users\Andrew\Documents\GitHub\SteamBot\Bin\Debug\dota2schema.txt"; 
      string schemaFilePath = @"C:\Users\Andrew\Documents\GitHub\SteamBot\Bin\Debug\schema.txt"; 

      string[] ingameschema = File.ReadAllLines(ingameschemaFilePath); 
      string[] dota2schema = File.ReadAllLines(dota2schemaFilePath); 
      string[] current = null; 
      string[] name = null; 
      string[] defindex = null; 
      string[] rarity = null; 

      using (TextWriter textWriter = new StreamWriter(schemaFilePath)) 
      { 
       foreach (//search for "name"->"name" segment here) 
       { 
        // if current.Contains("dota_item_wearable") == false, current.Contains("announcer", "courier", "ward", "egg", "costume", "HUD", "smeevil", "taunt", "bait", "lure", "bundle") == true, 
        //   break 
        } 
       } 
      System.Console.WriteLine("Press any key to exit."); 
      System.Console.ReadKey(); 
    } 
    } 
} 
+4

Как вы думаете, вы могли бы показать нам начало и конец этого файла? У меня такое чувство, что это JSON, и в этом случае у вас может быть гораздо лучший вариант, чем Regex. – Katana314

+0

Он немного похож на JSON, но без брекетов {}. Является ли входной файл действительным JSON, или это просто длинный список без разделения для каждого элемента элемента? Если это JSON, есть несколько отличных библиотек, которые будут анализировать файл в аккуратные объекты для вас. Я сам поклонник JSON.NET, но есть и другие хорошие. – McMuttons

+0

Start: "результат" { \t: { \t \t "Статус": 1, \t \t "items_game_url": «HTTP: \/\/media.steampowered.com \/Apps \/570 \/скрипты \ /items\/items_game.***************..txt», \t \t "качества": { \t \t \t "нормальный": 0, \t \t \t "подлинной": 1, \t \t \t "винтаж": 2, \t \t \t "необычный": 3 , \t \t \t "уникальный": 4, \t \t \t "сообщество": 5, \t \t \t "разработчик": 6, \t \t \t "самодельных": 7, \t \t \t "настроить": 8, \t \t \t "странно": 9, \t \t \t "завершено": 10, \t \t \t "привидениями": 11, \t \t \t "турнир": 12, \t \t \t "благоприятствования": 13 – user2688799

ответ

0

Я думаю, вы должны использовать StreamReader читать построчно из текстового файла, а затем найти нужную информацию в этой строке.

Существует только проблема, если вы сохраняете часть файла до тех пор, пока не закончите читать его, тогда вы можете столкнуться с проблемами памяти (но вы удивитесь, насколько велики вы можете позволить спискам & Словари до вас закончилась нехватка памяти)

Что вам нужно сделать, это сохранить обработанные данные, как только сможете, и не хранить их в памяти (или сохранить как можно меньше в памяти).

+0

Зачем ему это нужно, когда .NET имеет Deserializer, разработанный, чтобы помочь вам это сделать при работе с JSON – MethodMan

+0

@DJKRAZE, и я думаю, что у вас правильно 7mb - это не так много данных, но при этом будет применяться определенный предел в подобных случаях , –

+0

Я бы предложил читать на 'JSON' Я не уверен, как вы придумываете эти непроверенные предположения извините – MethodMan

0

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

Пример

static void Main(string[] args) 
    { 
     string sourcefile = @"C:\test\source.txt"; 
     string outputfile = @"C:\test\output.txt"; 

     string[] source = File.ReadAllLines(sourcefile); 

     // The list would represent the collection of all the items 
     List<NameValueCollection> list = new List<NameValueCollection>(); 

     // Each nvc would represent the collection of attributes for that item 
     NameValueCollection nvc = null; 

     foreach (string s in source) 
     { 
      //Split your string into its key and value 
      string[] nv = s.Split(':'); 

      //If the key is name you have finished your previous item, and will it to the list and start a new one 
      if (nv[0] == "name") 
      { 
       if (nvc != null) 
        list.Add(nvc); 

       nvc = new NameValueCollection(); 
      } 
      // Add your attribute and value to the items attribute collection 
      nvc.Add(nv[0], nv[1]); 
     } 
    } 

7mb немного большим, но с сегодняшней памяти, вы должны быть в порядке. Если это станет проблемой, вы можете вместо этого использовать ReadLine из объекта Stream, который будет загружать каждую строку в память по одному за раз.

Дайте мне знать, если это вообще поможет.

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