Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
java-lekcii-2016-01-17 / presentation-nov-28.docx
Скачиваний:
14
Добавлен:
27.03.2016
Размер:
44.49 Кб
Скачать

Ru.Mami.FileCache

package ru.mami;

import java.io.IOException;

import java.nio.file.Files;

import java.nio.file.Path;

import java.nio.file.Paths;

import java.nio.file.StandardOpenOption;

import java.util.Arrays;

import java.util.LinkedList;

import java.util.List;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

public final class FileCache {

private Pattern pattern;

private int targetGroupIndex;

private Path file;

public FileCache(String fileAddress) {

// Получение Path из указанного адреса

file = Paths.get(fileAddress);

// создание шаблона из стандартного регулярного выражения (что угодно

// кроме '|')

// () - группа

// [символы] - любой из символов внутри квадратных скобок

// [^символы] - любой символ, кроме тех, которые находятся внутри

// квадратных скобок

// * - ноль или более совпадений

// [^|]* - ноль или более любых символов, кроме '|'

// $ - конец строки

// \\| - символ '|', экранированный при помощи \\, чтобы сообщить

// компилятору, что это именно '|', а не 'или', так как вне квадратных

// скобок многие символы (в том числе этот) имеют специальное значение

// ([^|]*)($|\\|) - ноль или более любых символов, кроме '|', сразу

// после которых идет либо '|', либо конец строки

pattern = Pattern.compile("([^|]*)($|\\|)");

// индекс группы, в которой находятся нужные данные (0 - все что совпало

// с регулярным выражением, 1 и далее - круглые скобки по порядку)

targetGroupIndex = 1;

}

public FileCache(String fileAddress, String regex, int targetGroupIndex) {

file = Paths.get(fileAddress);

// создание шаблона из предоставленного регулярного выражения

pattern = Pattern.compile(regex);

this.targetGroupIndex = targetGroupIndex;

}

/**

* Поиск совпадения в кэше (поиск в файле, заданном при создании класса,

* строки, в которой первые несколько подстрок, соответствующие шаблону,

* заданному при создании класса, в точности совпадают с предоставленными

* значениями

*

* Метод написан для вынесения общего куска кода из методов loadOne и

* loadAll

*

* @param values

* значения, которые должны совпасть, чтобы запись в кэше

* считалась найденной (параметры задачи)

* @return объект класса Matcher, указывающий на подстроку, совпавшую с

* последним значением в values (т.о. следующий вызов matcher.find()

* передвинет указатель на первый результат вычисления) или null,

* если строки найти не удалось

*/

private Matcher findMatch(String... values) {

// если такого файла нет, сразу вернуть null

if (!Files.exists(file)) {

return null;

}

try {

// прочитать все строки файла в список строк

List<String> lines = Files.readAllLines(file);

// для каждой строки

for (String line : lines) {

// создать Matcher

Matcher matcher = pattern.matcher(line);

// начинать искать совпадения с первого элемента массива values

int index = 0;

// пока индекс текущего элемента массива values на превысил

// количество элементов массива (index < values.length)

// и существует следующая подстрока, соответствующая шаблону

// (matcher.find())

// и эта подстрока в точности соответствует текущему элементу

// массива values (matcher.group().equals(values[index]))

while (index < values.length && matcher.find()

&& matcher.group(targetGroupIndex)

.equals(values[index])) {

// переходить к следующему элементу

++index;

}

// если для всех элементов массива нашлось совпадение

if (index == values.length) {

// вернуть этот Matcher

return matcher;

}

}

// если ни в одной строке совпадения не нашлись, вернуть null

return null;

} catch (IOException e) {

// если возникла ошибка при чтении файла, вернуть null

return null;

}

}

/**

* Поиск совпадения в кэше (поиск в файле, заданном при создании класса,

* строки, в которой первые несколько подстрок, соответствующие шаблону,

* заданному при создании класса, в точности совпадают с предоставленными

* значениями)

*

* @param values

* значения, которые должны совпасть, чтобы запись в кэше

* считалась найденной (параметры задачи)

* @return список (List<String>) всех остальных подстрок, соответствующих

* шаблону, найденных в этой строке (результаты решения задачи), или

* null, если такой строки обнаружить не удалось

*/

public List<String> loadAll(String... values) {

// получить Matcher из функции findMatch

Matcher matcher = findMatch(values);

// если возвращенное значение не null и у матчера есть другие подстроки,

// совпавшие с шаблоном

if (matcher != null && matcher.find()) {

// создать новый список

List<String> result = new LinkedList<String>();

// поместить в него все подстроки из матчера

do {

result.add(matcher.group(targetGroupIndex));

} while (matcher.find());

return result;

}

// иначе вернуть null

return null;

}

/**

* Поиск совпадения в кэше (поиск в файле, заданном при создании класса,

* строки, в которой первые несколько подстрок, соответствующие шаблону,

* заданному при создании класса, в точности совпадают с предоставленными

* значениями)

*

* Метод написан для удобства, чтобы не работать со списком, состоящим из

* одного элемента

*

* @param values

* значения, которые должны совпасть, чтобы запись в кэше

* считалась найденной (параметры задачи)

* @return одна подстрока, соответствующая шаблону, идущая в этой строке

* сразу после параметров (единственый результат решения задачи),

* или null, если такой строки обнаружить не удалось

*/

public String loadOne(String... values) {

// получить Matcher из функции findMatch

Matcher matcher = findMatch(values);

// если возвращенное значение не null и у матчера есть другие подстроки,

// совпавшие с шаблоном

if (matcher != null && matcher.find()) {

// вернуть следующую подстроку из матчера

return matcher.group(targetGroupIndex);

}

// иначе вернуть null

return null;

}

/**

* Сохранение значения в кэше

*

* @param values

* значения, которые надо сохранить (параметры и результаты

* решения задачи)

*/

public void save(String... values) {

// объединить полученный массив строк в одну строку, разделив все

// значения символом '|'

String line = String.join("|", values);

try {

// дописать эту строку в файл

Files.write(file, Arrays.asList(line),

StandardOpenOption.CREATE,

StandardOpenOption.APPEND);

} catch (IOException e) {

e.printStackTrace();

}

}

}

Соседние файлы в папке java-lekcii-2016-01-17