Отображение строк из InputStream в ExecutorService - PullRequest
0 голосов
/ 12 ноября 2018

Я реализую свой DIY IoT.У меня есть центральный узел (сервер), который получает команды из разных источников и выполняет их.

Формат ввода:

<DEVICE_NAME>_<COMMAND> <DEVICE_NAME>_<COMMAND>  <DEVICE_NAME>_<COMMAND>
<DEVICE_NAME>_<COMMAND>  <DEVICE_NAME>_<COMMAND> 
<DEVICE_NAME>_<COMMAND>  <DEVICE_NAME>_<COMMAND>  <DEVICE_NAME>_<COMMAND> 

Каждая строка может содержать несколько команд.

Я реализовал сервер-исполнитель команд, который принимает команды из сеанса как InputStream.Затем я разделяю данные и обрабатываю их:

private Device c0 = // Device constructor
private Device c1 = // Device constructor
private Device c2 = // Device constructor
private Device c3 = // Device constructor

private ExecutorService executor = Executors.newFixedThreadPool(3);

public void onConnection(InputStream in)     
    InputStreamReader isr = new InputStreamReader(in);
    LineNumberReader reader = new LineNumberReader(isr);

    String line = null;
    while ((line = reader.readLine()) != null) {
        String[] strings = line.split(",");
        for (String raw : strings) {
            String command = raw.substring(0, 3);
            if (raw.startsWith("C0_")) {
                executor.submit(() -> c0.execute(command));
            } else if (raw.startsWith("C1_")) {
                executor.submit(() -> c1.execute(command));
            } else if (raw.startsWith("C2_")) {
                executor.submit(() -> c2.execute(command));
            } else if (raw.startsWith("C3_")) {
                executor.submit(() -> c3.execute(command));
            }
        }
    }
}

Я понимаю, что код выглядит ужасно.У вас есть идеи по улучшению?Может быть, я мог бы использовать Steam API?Любые советы и подсказки приветствуются.

ОБНОВЛЕНИЕ

Я попытался немного очистить код, отправив задачу только один раз, но компилятор говорит, что device должно быть finalили effectively final, так что это не работает:

String command = raw.substring(0, 3);
Device device;
if (raw.startsWith("C0_")) {
    device = c0;
} else if (raw.startsWith("C1_")) {
    device = c1;
} else if (raw.startsWith("C2_")) {
    device = c2;
} else if (raw.startsWith("C3_")) {
    device = c3;
}
executor.submit(() -> device.execute(command));

1 Ответ

0 голосов
/ 12 ноября 2018

Вы можете отобразить ваши команды так:

InputStreamReader isr = new InputStreamReader(is);
BufferedReader buffReader = new BufferedReader(isr);

Map<String, List<String>> map = buffReader.lines()
            .map(s -> s.split(" "))
            .flatMap(Arrays::stream)
            .map(s -> s.split("(?<=_)", 2))
            .collect(groupingBy(p -> p[0], mapping(p -> p[1], toList())));

Обновление

На самом деле вы можете комбинировать отображение и отправку:

// Register your devices
Map<String, Device> devices = new HashMap<>();
devices.put("c0", c0);
devices.put("c1", c1);
devices.put("c2", c2);
devices.put("c3", c3);
...

public void onConnection(InputStream in) {
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader buffReader = new BufferedReader(isr);
    buffReader.lines()
              .parallel()
              .map(s -> s.split(" "))
              .flatMap(Arrays::stream)
              .map(s -> s.split("(?<=_)", 2))
              .forEach(p -> executor.submit(
                      () -> devices.get(p[0]).execute(p[1])
               ));
}
...