O código Scala normalmente usa classes Java para lidar com E / S, incluindo diretórios de leitura. Então você tem que fazer algo como:
import java.io.File
def recursiveListFiles(f: File): Array[File] = {
val these = f.listFiles
these ++ these.filter(_.isDirectory).flatMap(recursiveListFiles)
}
Você pode coletar todos os arquivos e filtrar usando um regex:
myBigFileArray.filter(f => """.*\.html$""".r.findFirstIn(f.getName).isDefined)
Ou você pode incorporar o regex na pesquisa recursiva:
import scala.util.matching.Regex
def recursiveListFiles(f: File, r: Regex): Array[File] = {
val these = f.listFiles
val good = these.filter(f => r.findFirstIn(f.getName).isDefined)
good ++ these.filter(_.isDirectory).flatMap(recursiveListFiles(_,r))
}
listFiles
retornanull
sef
não apontar para um diretório ou se houver um erro de IO (pelo menos de acordo com a especificação Java). Adicionar uma verificação nula é provavelmente uma boa opção para uso em produção.f.isDirectory
retornar verdadeiro, masf.listFiles
retornarnull
. Por exemplo, se você não tiver permissão para ler os arquivos, receberá umnull
. Em vez de ter as duas verificações, eu apenas adicionaria uma verificação nula.f.listFiles
retorna nulo quando!f.isDirectory
.Eu preferiria uma solução com Streams porque você pode iterar em um sistema de arquivos infinito (Streams são coleções avaliadas lentamente)
Exemplo para pesquisar
fonte
def getFileTree(f: File): Stream[File] = f #:: Option(f.listFiles()).toStream.flatten.flatMap(getFileTree)
A partir do Java 1.7, todos devem estar usando java.nio. Ele oferece desempenho próximo ao nativo (java.io é muito lento) e tem alguns auxiliares úteis
Mas o Java 1.8 apresenta exatamente o que você está procurando:
Você também solicitou a correspondência de arquivos. Experimente
java.nio.file.Files.find
e tambémjava.nio.file.Files.newDirectoryStream
Veja a documentação aqui: http://docs.oracle.com/javase/tutorial/essential/io/walk.html
fonte
http://langref.org/scala+java/files
fonte
Scala é uma linguagem multiparadigma. Uma boa maneira "scala-esque" de iterar um diretório seria reutilizar um código existente!
Eu consideraria o uso de commons-io uma maneira perfeitamente scala-esque de iterar um diretório. Você pode usar algumas conversões implícitas para tornar mais fácil. Gostar
fonte
Eu gosto da solução de stream do yura, mas ela (e as outras) recorre para diretórios ocultos. Também podemos simplificar, utilizando o fato de que
listFiles
retorna null para um não diretório.Agora podemos listar arquivos
ou realizar todo o fluxo para processamento posterior
fonte
O FileUtils do Apache Commons Io cabe em uma linha e é bastante legível:
fonte
Ninguém mencionou ainda https://github.com/pathikrit/better-files
fonte
Dê uma olhada em scala.tools.nsc.io
Existem alguns utilitários muito úteis lá, incluindo funcionalidade de listagem detalhada na classe Directory.
Se bem me lembro, isso foi destacado (possivelmente contribuído) por retronímia e foi visto como um paliativo antes que o io obtenha uma implementação nova e mais completa na biblioteca padrão.
fonte
E aqui está uma mistura da solução de fluxo de @DuncanMcGregor com o filtro de @ Rick-777:
Isso dá a você um Stream [Arquivo] em vez de uma (potencialmente grande e muito lenta) Lista [Arquivo], enquanto permite que você decida quais tipos de diretórios serão recursivamente com a função descendCheck ().
fonte
E se
fonte
Scala tem a biblioteca 'scala.reflect.io' que é considerada experimental, mas faz o trabalho
fonte
Eu pessoalmente gosto da elegância e simplicidade da solução proposta por @Rex Kerr. Mas aqui está a aparência de uma versão recursiva de cauda:
fonte
Aqui está uma solução semelhante à de Rex Kerr, mas incorporando um filtro de arquivo:
O método retorna um List [File], que é um pouco mais conveniente do que Array [File]. Ele também ignora todos os diretórios que estão ocultos (ou seja, começando com '.').
É parcialmente aplicado usando um filtro de arquivo de sua escolha, por exemplo:
fonte
A solução mais simples somente Scala (se você não se importa em exigir a biblioteca do compilador Scala):
Caso contrário, a solução de @Reaud é curta e agradável (se você não se importar em usar o Apache Commons FileUtils):
Onde
dir
está um java.io.File:fonte
Parece que ninguém menciona a
scala-io
biblioteca do scala-incubrator ...Ou com
implicit
Ou se você quiser
implicit
explicitamente ...A documentação está disponível aqui: http://jesseeichar.github.io/scala-io-doc/0.4.3/index.html#!/file/glob_based_path_sets
fonte
Este encantamento funciona para mim:
fonte
Você pode usar recursão de cauda para isso:
fonte
Por que você está usando o arquivo Java em vez do AbstractFile do Scala?
Com o AbstractFile da Scala, o suporte ao iterador permite escrever uma versão mais concisa da solução de James Moore:
fonte