2015-07-22 3 views
0

У меня есть текстовые файлы, которые имеют атрибуты, сохраненные в Строках. Эти строки имеют шаблон, как это:Получение значений из строки с узорами

[attributeName]:[value] 

Я не могу обобщить [значение], потому что это может быть любого примитивного типа данных. Сохранение эффективных значений не является для меня проблемой, потому что это зависит от пользователя, который должен быть загружен атрибутом. Тот же файл не будет загружаться очень часто.

Теперь у меня есть 2 проблемы:

1) для какой-то причине программа, которая создает эти файлы иногда добавляет пространства вокруг: в некоторых атрибутах и ​​[значение] может также содержать пробелы, так что я должен избавиться от те

2) Создание чтение этих атрибутов более производительным:

я пришел с этим методом:

public String getAttribute(File file, String attribute) 
{ 
    try 
    { 
     BufferedReader reader = new BufferedReader(new FileReader(file), 1024); 
     String line; 
     Pattern p = Pattern.compile(Pattern.quote(attribute), Pattern.CASE_INSENSITIVE); 
     while ((line = reader.readLine()) != null) 
     { 
      int i = line.indexOf(":"); 

      if(line.charAt(i-1) == ' ') 
       line = line.substring(0,i-2) + line.substring(i); 

      if(line.charAt(i+1) == ' ') 
       line = line.substring(0,i) + line.substring(i+2); 

      if (p.matcher(line).find()) 
      { 
       return line.replace(attribute, "").trim(); 
      } 

     } 
    } catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 

    return null; 
} 

Howev er, этот метод, вероятно, будет одним из самых популярных моих приложений, поэтому я не могу оставить его настолько неэффективным, как сейчас, Спасибо за любую помощь!

ответ

1
  1. Я модифицировал код, чтобы найти подходящую линию. Проверьте примерный код ниже.
  2. Если у вас есть много файлов и атрибутов в этих файлах, вы можете подумать о сохранении где-то пара атрибута = значение в коде. В примере кода я предоставил очень примитивный кэш, используя интерфейс Table из библиотеки guava.

Пример кода:

# guava library 
import com.google.common.collect.Table; 
import com.google.common.collect.HashBasedTable; 

# apache commons lang 
import static org.apache.commons.lang.StringUtils.startsWithIgnoreCase; 
# apache commons io 
import static org.apache.commons.io.IOUtils.closeQuietly; 
[...] 
# very primitive cache implementation. To find a value in table you have to 
# pass row and column keys. In this implementation row is equal to file 
# absolute path (because you can have 2 files with the same name) and column 
# is equal to attribute name. 
# If you have a lot of files and attributes probably you will have to clear 
# from time to time the cache otherwise you will get out of memory 
private static final Table<String, String, String> CACHE = HashBasedTable.create(); 
[...] 
public String getAttribute(File file, String attribute) { 
    # get value for the given attribute from the given file 
    String value = CACHE.get(file.getAbsolutePath(), attribute);   

    # if cache does not contain value, method will read value from file 
    if (null == value) { 
     BufferedReader reader = null; 
     String value = null; 

     try { 
      reader = new BufferedReader(new FileReader(file), 1024); 
      String line; 

      while ((line = reader.readLine()) != null) { 
       # From your description I understood that each line in file 
       # starts with attribute name 
       if (startsWithIgnoreCase(line, attribute) { 
        # if we found correct line we simple split it by ':' 
        String[] array = line.split(":"); 

        # this is to ensure that line contains attribute name 
        # and value 
        if (array.length >= 2) { 
         # we found value for attribute and we remove spaces 
         value = array[1].trim(); 
         # we put value to the cache to speed up finding 
         # value for the same attribute in the future 
         CACHE.put(file.getAbsolutePath(), attribute, value); 
         break; 
        } 
       } 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      # you should always close 
      closeQuietly(reader); 
     } 
    } 

    return value; 
} 
+0

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

+0

После прочтения кода во второй раз, я видел, что это может быть уже мое решение, которое лишь небольшая корректировка. Благодаря! –

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