Поиск файлов в каталоге и их сопряжение на основе общей подстроки
Я пытался запрограммировать решение для 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
Это предпочтительнее для файлового решения из-за нескольких вещей:
- Это значительно более информативно при сбое
- Он чище и более лаконичен, чем ваше файловое решение, и не требует проверки на ноль
- Это совместимо вперед, и, следовательно, предпочтительнее, чем
File
Решение на основе
Files.find
доступен с Java 8 и выше