使用模式从字符串中获取值

时间:2015-07-22 20:22:48

标签: string performance file

我有文本文件,其中包含保存在字符串中的属性。这些字符串有这样的模式:

[attributeName]:[value]

我无法概括[value],因为它可能是任何原始数据类型。 保存有效值不是我关注的问题,因为它取决于用户必须加载哪个属性。不会经常加载相同的文件。

现在我有两个问题:

1)由于某种原因,创建这些文件的程序有时会在:某些属性周围添加空格,[value]也可能包含空格,所以我必须摆脱那些

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;
}

但是,这个方法可能是我的应用程序调用最多的方法之一,所以我不能让它像现在这样无法使用, 谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

  1. 我修改了代码以找到合适的行。检查下面的示例代码。
  2. 如果这些文件中有很多文件和属性,您可以考虑在代码中保存某个对的attribute = value。在示例代码中,我使用Table库中的guava接口提供了非常原始的缓存。
  3. 示例代码:

    # 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;
    }