Поиск файлов в каталоге и их сопряжение на основе общей подстроки

Я пытался запрограммировать решение для ImageJ для обработки моих изображений.

Я понимаю, как получить каталог, выполнить команды для него и т. Д. И т. Д. Однако я столкнулся с ситуацией, когда мне теперь нужно начать использовать какой-либо тип функции поиска для объединения двух изображений в каталог, полный пар изображений.,

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

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

Общий формат этих изображений:

  • someString_DAPI_0001.tif
  • someString_GFP_0001.tif
  • someString_DAPI_0002.tif
  • someString_GFP_0002.tif
  • someString_DAPI_0003.tif
  • someString_GFP_0003.tif

Они расположены в алфавитном порядке, поэтому можно перейти к следующему изображению в списке. Я просто немного растерялся, какие функции я должен использовать для достижения этой цели, но я думаю, что моя общая структура правильна. Благодаря некоторой помощи от форумов Java. Однако я все еще застрял на том, куда идти дальше.

Итак, вот мой код: благодаря этому SO ответ для частичного кода

int count = 0;
getFile("C:\");

string DAPI;
string GFP;


private void getFile(String dirPath) {
    File f = new File(dirPath);
    File[] files = f.listFiles();

    while (files.length > 0) {
        if (/* File name contains "DAPI"*/){
            DAPI = File f;
            string substitute to get 'GFP' filename
            store GFP file name into variable
            do something(DAPI, GFP);
        }
        advance to next filename in list
    }
}

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

Я также понятия не имею, какая функция будет использоваться для замены подстрок.

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

2 ответа

Решение

Не похоже, что вам нужно регулярное выражение, если имена ваших файлов следуют простому шаблону, который вы упомянули. Вы можете просто перебирать файлы и фильтровать их в зависимости от того, содержит ли имя файла DAPI, например, см. Ниже. Этот код может быть упрощением ваших требований, но я не могу сказать это на основании предоставленной вами информации.

import java.io.*;


public class Temp {

  int count = 0;

  private void getFile(String dirPath) {
    File f = new File(dirPath);
    File[] files = f.listFiles();

    if (files != null) {
      for (File file : files) {
        if (file.getName().contains("DAPI")) {
          String dapiFile = file.getName();
          String gfpFile = dapiFile.replace("DAPI", "GFP");
          doSomething(dapiFile, gfpFile);
        }
      }
    }
  }

  //Do Something does nothing right now, expand on it.
  private void doSomething(String dapiFile, String gfpFile) {
    System.out.println(new File(dapiFile).getAbsolutePath());
    System.out.println(new File(gfpFile).getAbsolutePath());
  }

  public static void main(String[] args) {
    Temp app = new Temp();
    app.getFile("C:\\tmp\\");
  }

}

ПРИМЕЧАНИЕ. Согласно ответу Vogel612, если у вас есть Java 8 и вам нравится функциональное решение, вы можете иметь:

private void getFile(String dirPath) {
  try {
    Files.find(Paths.get(dirPath), 1, (path, basicFileAttributes) -> (path.toFile().getName().contains("DAPI"))).forEach(
      dapiPath -> {
        Path gfpPath = dapiPath.resolveSibling(dapiPath.getFileName().toString().replace("DAPI", "GFP"));
        doSomething(dapiPath, gfpPath);
      });
  } catch (IOException e) {
    e.printStackTrace();
  }
}

//Dummy method does nothing yet.
private void doSomething(Path dapiPath, Path gfpPath) {
  System.out.println(dapiPath.toAbsolutePath().toString());
  System.out.println(gfpPath.toAbsolutePath().toString());
}

С помощью java.io.File это неправильный способ подойти к этой проблеме. То, что вы ищете, это потоковое решение, использующее Files.find это будет выглядеть примерно так:

 Files.find(dirPath, 1, (path, attributes) -> {
     return path.getFileName().toString().contains("DAPI");
 }).forEach(path -> {
    Path gfpFile = path.resolveSibling(/*build GFP name*/);
    doSomething(path, gfpFile);
 });

Что это делает:

  • Перебрать все Path ниже dirPath 1 уровень глубины (можно отрегулировать)
  • Проверьте, что имя файла содержит "DAPI"
  • Используйте эти файлы, чтобы найти соответствующие "GFP" -Файл
  • дать им doSomething

Это предпочтительнее для файлового решения из-за нескольких вещей:

  1. Это значительно более информативно при сбое
  2. Он чище и более лаконичен, чем ваше файловое решение, и не требует проверки на ноль
  3. Это совместимо вперед, и, следовательно, предпочтительнее, чем File Решение на основе

Files.find доступен с Java 8 и выше

Другие вопросы по тегам