Esto debería ser realmente simple. Si tengo una cadena como esta:
../Test?/sample*.txt
entonces, ¿cuál es una forma generalmente aceptada de obtener una lista de archivos que coinciden con este patrón? (por ejemplo, debe coincidir ../Test1/sample22b.txt
y ../Test4/sample-spiffy.txt
no ../Test3/sample2.blah
o ../Test44/sample2.txt
)
He echado un vistazo org.apache.commons.io.filefilter.WildcardFileFilter
y parece la bestia correcta, pero no estoy seguro de cómo usarlo para encontrar archivos en una ruta de directorio relativa.
Supongo que puedo buscar la fuente de hormiga ya que usa la sintaxis comodín, pero debo estar perdiendo algo bastante obvio aquí.
( editar : el ejemplo anterior fue solo un caso de ejemplo. Estoy buscando la forma de analizar rutas generales que contienen comodines en tiempo de ejecución. Descubrí cómo hacerlo basándose en la sugerencia de mmyers, pero es un poco molesto. Sin mencionar que el JRE de Java parece analizar automáticamente los comodines simples en los principales (argumentos de Cadena []) desde un solo argumento para "ahorrarme" tiempo y molestias ... Me alegra no haber tenido argumentos que no sean de archivo en el mezcla.)
Respuestas:
Considere DirectoryScanner de Apache Ant:
Deberá hacer referencia a ant.jar (~ 1.3 MB para ant 1.7.1).
fuente
DirectoryScanner
se encuentra en plexus-utils (241Kb). Que es más pequeño queant.jar
(1.9Mb).ls
con el mismo patrón de archivo (milisegundos usandols <pattern>
vs. minutos cuando usa el DirectoryScanner) ...Pruebe
FileUtils
con Apache commons-io (listFiles
yiterateFiles
métodos):Para resolver su problema con las
TestX
carpetas, primero iteraría a través de la lista de carpetas:Toda una solución de 'fuerza bruta' pero debería funcionar bien. Si esto no se ajusta a sus necesidades, siempre puede usar RegexFileFilter .
fuente
Estos son ejemplos de archivos de listado por patrón con tecnología Java 7 nio globbing y Java 8 lambdas:
o
fuente
Files.walk(Paths.get("..")).filter(matcher::matches).forEach(System.out::println);
Puede convertir su cadena comodín en una expresión regular y usarla con el
matches
método de String . Siguiendo tu ejemplo:Esto funciona para tus ejemplos:
Y contraejemplos:
fuente
?
public static boolean isFileMatchTargetFilePattern (Archivo final f, String final targetPattern) {`` String regex = targetPattern.replace (".", "\\."); `regex = regex.replace("?", ".?").replace("
*", ".
*");
return f.getName().matches(regex);
}
StringBuffer regexBuffer = ...; Matcher matcher = Pattern.compile("(.*?)([*?])").matcher(original); while (matcher.find()) { matcher.appendReplacement(regexBuffer, (Pattern.quote(matcher.group(1)) + (matcher.group(2).equals("*") ? ".*?" : ".?")).replace("\\", "\\\\").replace("$", "\\$")); } matcher.appendTail(regexBuffer);
.
lugar de.?
.Desde Java 8 puede usar el
Files#find
método directamente desdejava.nio.file
.Ejemplo de uso
fuente
Es posible que no lo ayude en este momento, pero JDK 7 está diseñado para que el nombre de archivo glob y regex coincida como parte de "Más características de NIO".
fuente
La biblioteca de comodines realiza eficientemente la coincidencia de nombres de archivo glob y regex:
http://code.google.com/p/wildcard/
La implementación es sucinta: JAR tiene solo 12.9 kilobytes.
fuente
Manera simple sin usar ninguna importación externa es usar este método
Creé archivos csv nombrados con billing_201208.csv, billing_201209.csv, billing_201210.csv y parece que funciona bien.
La salida será la siguiente si los archivos enumerados anteriormente existen
fuente
Como se publicó en otra respuesta, la biblioteca de comodines funciona tanto para la coincidencia de nombres de globo y expresiones regulares: http://code.google.com/p/wildcard/
Utilicé el siguiente código para hacer coincidir patrones globales que incluyen absoluto y relativo en los sistemas de archivos de estilo * nix:
Pasé un tiempo tratando de obtener los métodos FileUtils.listFiles en la biblioteca io de Apache commons (vea la respuesta de Vladimir) para hacer esto, pero no tuve éxito (ahora me doy cuenta / creo que solo puede manejar patrones que coinciden con un directorio o archivo a la vez) .
Además, el uso de filtros regex (ver la respuesta de Fabian) para procesar patrones globales glob de tipo absoluto proporcionados por el usuario sin buscar en todo el sistema de archivos requeriría un cierto preprocesamiento del glob suministrado para determinar el prefijo más grande no regex / glob.
Por supuesto, Java 7 puede manejar bien la funcionalidad solicitada, pero desafortunadamente estoy atascado con Java 6 por ahora. La biblioteca es relativamente minúscula con un tamaño de 13.5 kb.
Nota para los revisores: Intenté agregar lo anterior a la respuesta existente que menciona esta biblioteca, pero la edición fue rechazada. Tampoco tengo suficiente representante para agregar esto como comentario. ¿No hay una mejor manera ...
fuente
Deberías poder usar el
WildcardFileFilter
. Solo useSystem.getProperty("user.dir")
para obtener el directorio de trabajo. Prueba esto:No debería ser necesario reemplazar
*
con[.*]
, suponiendo que utiliza el filtro de comodínjava.regex.Pattern
. No he probado esto, pero uso patrones y filtros de archivos constantemente.fuente
Glob of Java7: Encontrar archivos . ( Muestra )
fuente
El filtro Apache está diseñado para iterar archivos en un directorio conocido. Para permitir los comodines en el directorio también, tendría que dividir la ruta en '
\
' o '/
' y hacer un filtro en cada parte por separado.fuente
¿Por qué no usar hacer algo como:
Entonces no tendrá que preocuparse por los caminos relativos y puede hacer su comodín según sea necesario.
fuente
Implemente la interfaz JDK FileVisitor. Aquí hay un ejemplo http://wilddiary.com/list-files-matching-a-naming-pattern-java/
fuente
Método Util:
Prueba de unidad:
Salida:
fuente
foo/bar.txt
coincidefoo?bar.txt
y eso no es correcto../Test?/sample*.txt
fuente