Прочитайте файл и получите ключ = значение без использования java.util.Properties - PullRequest
3 голосов
/ 16 февраля 2012

Я создаю RMI-игру, и клиент загружает файл с некоторыми ключами и значениями, которые будут использоваться на нескольких различных объектах.Это файл с сохранением игры, но я не могу использовать для этого java.util.Properties (он соответствует спецификации).Я должен прочитать весь файл и игнорировать закомментированные строки и ключи, которые не имеют отношения к некоторым классам.Эти свойства являются уникальными, но они могут быть отсортированы в любом порядке.Текущий файл моего файла выглядит следующим образом:

# Bio
playerOrigin=Newlands
playerClass=Warlock
# Armor
playerHelmet=empty
playerUpperArmor=armor900
playerBottomArmor=armor457
playerBoots=boot109
etc

Эти свойства будут записаны и размещены в соответствии с прогрессом проигрывателя, и программа чтения файлов должна будет достичь конца файла и получить только соответствующие ключи.Я пробовал разные подходы, но пока ничто не приблизилось к результатам, которые я получил бы, используя java.util.Properties.Есть идеи?

Ответы [ 4 ]

5 голосов
/ 16 февраля 2012

Это будет читать ваш файл "свойств" построчно, анализировать каждую строку ввода и помещать значения в карту ключ / значение.Каждый ключ на карте уникален (дубликаты ключей не допускаются).

package samples;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.TreeMap;

public class ReadProperties {

    public static void main(String[] args) {
        try {
           TreeMap<String, String> map = getProperties("./sample.properties");
           System.out.println(map);
        }
        catch (IOException e) {
            // error using the file
        }
    }

    public static TreeMap<String, String> getProperties(String infile) throws IOException {
        final int lhs = 0;
        final int rhs = 1;

        TreeMap<String, String> map = new TreeMap<String, String>();
        BufferedReader  bfr = new BufferedReader(new FileReader(new File(infile)));

        String line;
        while ((line = bfr.readLine()) != null) {
            if (!line.startsWith("#") && !line.isEmpty()) {
                String[] pair = line.trim().split("=");
                map.put(pair[lhs].trim(), pair[rhs].trim());
            }
        }

        bfr.close();

        return(map);
    }
}

Вывод выглядит следующим образом:

{playerBoots=boot109, playerBottomArmor=armor457, playerClass=Warlock, playerHelmet=empty, playerOrigin=Newlands, playerUpperArmor=armor900}

Вы получаете доступ к каждому элементу карты с помощью map.get("key string");.

РЕДАКТИРОВАТЬ : этот код не проверяет наличие искаженной или отсутствующей строки "=".Вы можете добавить это самостоятельно при возврате из split, проверив размер массива пар.

2 голосов
/ 16 февраля 2012

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

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

1 голос
/ 17 февраля 2012

После некоторого изучения я придумал это решение:

public static String[] getUserIdentification(File file) throws IOException {
        String key[] = new String[3];
        FileReader fr = new FileReader(file);
        BufferedReader br = new BufferedReader(fr);
        String lines;
        try {
            while ((lines = br.readLine()) != null) {
                String[] value = lines.split("=");
                if (lines.startsWith("domain=") && key[0] == null) {
                    if (value.length <= 1) {
                        throw new IOException(
                                "Missing domain information");
                    } else {
                        key[0] = value[1];
                    }
                }

                if (lines.startsWith("user=") && key[1] == null) {
                    if (value.length <= 1) {
                        throw new IOException("Missing user information");
                    } else {
                        key[1] = value[1];
                    }
                }

                if (lines.startsWith("password=") && key[2] == null) {
                    if (value.length <= 1) {
                        throw new IOException("Missing password information");
                    } else {
                        key[2] = value[1];
                    }
                } else
                    continue;
            }
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return key;
}

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

1 голос
/ 16 февраля 2012

Кроме того, вы можете использовать регулярное выражение для получения пар ключ / значение.

(?m)^[^#]([\w]+)=([\w]+)$

возвратит группы захвата для каждого ключа и его значения и проигнорирует строки комментариев.

EDIT:

Это можно сделать немного проще:

[^#]([\w]+)=([\w]+)
...