Там какой-либо лучший путь состоит в том, чтобы сделать filefilter для многих расширение?

Вы находитесь на правильном пути с хэшем, вам просто нужно вычислить ключ по столбцам для каждой таблицы. Раздел решения:

  • считывают каждую строку из 3 файлов TSV, используя Text :: CSV
    • для каждой строки, вызывая специфичный для таблицы код ref
    • извлекает 2 столбца, которые необходимы для ключа, и объединяет их со строкой ключа $key
    • для первой таблицы: сохранить ключ в массиве @order, т.е. он определяет порядок вывода таблицы
    • в хеш-коде %table под ключом $key: поместите столбцы, идущие из этой таблицы в финальную таблицу, в массив ref
  • [ 1117] цикл по @order
    • извлекает ссылку на массив из $key из хэша %table
    • строки дампа как TSV, используя Text :: CSV - [119 ]
#!/usr/bin/perl
use warnings;
use strict;
use autodie;

use Text::CSV;

my $csv = Text::CSV->new({
    binary   => 1,
    eol      => "\n",
    sep_char => "\t",
}) or die "CSV creation\n";

sub read_file($) {
    my($file, $code) = @_;
    open(my $fh, '<', $file);
    while (my $row = $csv->getline( $fh )) {
        $code->($row);
    }
    $csv->eof or $csv->error_diag();
    close($fh);
}

# Output table + row order
my %table;
my @order;

# Table 1
read_file($ARGV[0], sub {
    my($row) = @_;

    #print "ROW 1 @{ $row }\n";
    my($col1, $col2) = @{ $row }[1,2];

    # column_1, column_2 define key
    my $key = "${col1}${col2}";
    #print "KEY 1 ${key}\n";

    # table 1 defines order
    push(@order, $key);
    # ID, column_1, column_2, column_3 from table 1
    $table{$key} = $row;
});

# Table 2
read_file($ARGV[1], sub {
    my($row) = @_;

    #print "ROW 2 @{ $row }\n";
    my($col4, $col5, $col6) = @{ $row };

    # column_4, column_5 define key
    my $key = "${col4}${col5}";
    #print "KEY 2 ${key}\n";

    # column_6 from table 2
    push(@{ $table{$key} }, $col6);
});

# Table 3
read_file($ARGV[2], sub {
    my($row) = @_;

    #print "ROW 3 @{ $row }\n";
    my($col7, $col8, $col9, $col10) = @{ $row };

    # column_7, column_10 define key
    my $key = "${col7}${col10}";
    #print "KEY 3 ${key}\n";

    # column_7, column_8 from table 2
    push(@{ $table{$key} }, $col7, $col8);
});

foreach my $key (@order) {
    $csv->print(\*STDOUT, $table{$key});
}

exit 0;

Тестовый прогон:

$ perl dummy.pl dummy1.txt dummy2.txt dummy3.txt 
A       100     100001  X       X       100     120000
B       100     99999   Y       Y       100     66666
C       100     88888   Z       Z       100     77777
D       99      100001  Y       Y       99      100000
E       99      88888   Z       Z       99      44444

10
задан Georg Schölly 14 May 2009 в 18:55
поделиться

7 ответов

Для Java 6 или выше это идеальный случай для FileNameExtensionFilter ... за исключением того, что он расширяет javax.swing.filechooser.FileFilter вместо реализации java.io.FileFilter .
Но написать обёртку для него - тривиальная задача:

File[] files = rootDir.listFiles(new FileFilter() {
    private final FileNameExtensionFilter filter =
        new FileNameExtensionFilter("Compressed files",
            "zip", "jar", "z", "gz", "tar", "bz2", "bz");
    public boolean accept(File file) {
        return filter.accept(file);
    }
});
17
ответ дан 3 December 2019 в 15:22
поделиться

Почему бы не использовать регулярные выражения?

static final Pattern p = Pattern.compile ("\\. (Zip | jar | z | gz) $");

а затем return p.matcher (name) .find ();

5
ответ дан 3 December 2019 в 15:22
поделиться

Некоторые решения псевдокода:

Итерация массив

suffixes = [".tar", ".zip", ".jpg"]

for suffix in suffixes:
    if name.endsWith(suffix):
        return True

Используйте набор

suffixes = [".tar", ".zip", ".jpg"]

nameSuffix = name.getSuffix()
if nameSuffix in suffixes:
    return True
5
ответ дан 3 December 2019 в 15:22
поделиться

Я только что закончил писать этот класс:

class FileExtensionFilter implements FileFilter {

    private final String[] validExtensions;

    public FileExtensionFilter(String... validExtensions) {
        this.validExtensions = validExtensions;
    }

    public boolean accept(File pathname) {
        if (pathname.isDirectory()) {
            return true;
        }

        String name = pathname.getName().toLowerCase();

        for (String ext : validExtensions) {
            if (name.endsWith(ext)) {
                return true;
            }
        }

        return false;
    }
}

использование:

File files[] = directory.listFiles(
                  new FileExtensionFilter(".zip", ".jar", ".z", ".tar"));

Кстати, это многоразовый class, вы даже можете обернуть его дополнительными проверками, используя шаблон декоратора и т. д.

PS

только что заметил существование FileNameExtensionFilter

1
ответ дан 3 December 2019 в 15:22
поделиться

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

nb FilenameUtils принадлежит Commons I / O , который также включает в себя набор классов, которые упрощают выполнение подобных действий. Взгляните также на FileFilterUtils , который еще больше упрощает работу и предоставляет несколько полезных вспомогательных методов.

private static Set allowedExtensions = null;

static {
    allowedExtensions = new HashSet<String>();
    allowedExtensions.add("txt");
    allowedExtensions.add("zip");
    allowedExtensions.add("jar");
    allowedExtensions.add("gz");
}

public void filter() {
    File rootDir = new File("/");
    File files[] = rootDir.listFiles(new FileFilter() {

        public boolean accept(File file) {

            if (file.isDirectory()) return true;

            String fileName = file.getName().toLowerCase();

            String extension = FilenameUtils.getExtension(fileName);
            if (StringUtils.isNotEmpty(extension)
                && allowedExtensions.contains(extension)) {
                return true;
            } else {
                return false;
            }
        }
    });        
}

Вы можете найти API здесь:

http : //commons.apache.org/io/api-release/

1
ответ дан 3 December 2019 в 15:22
поделиться

Вы можете статически создать карту и вернуть истину, если расширение имени файла является ключом в карте.

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

0
ответ дан 3 December 2019 в 15:22
поделиться

Вот мой подход. java.lang.Collections - действительно хороший класс! И поскольку мы ищем данное расширение файла в HashSet, оно более производительно. Хотя сомневаюсь, что в данном случае производительность действительно имеет значение ...

// ...

final Set<String> archives = new HashSet<String>();
Collections.addAll(archives, ".zip", ".jar", ".z", ".gz", ".tar",
        ".bz2", ".bz");

File files[] = rootDir.listFiles(new FileFilter() {
    public boolean accept(final File file) {
        if (file.isDirectory())
            return true;

        final String name = file.getName().toLowerCase();
        return archives.contains(name
                .substring(name.lastIndexOf('.')));

    }
});

// ...
0
ответ дан 3 December 2019 в 15:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: