Исключить расширения файлов для компилятора на основе Java? - PullRequest
0 голосов
/ 08 ноября 2018

Я обычно нахожу обходной путь для проблем, но на этот раз я не могу найти его.

Я делаю компилятор для самостоятельно разработанного языка с использованием JavaCC. Раньше я просто использовал System.in для чтения файлов, поэтому я знаю, что мой компилятор может использовать любой текстовый файл с любым расширением.

Этот проект должен открывать только файлы с пользовательским расширением (.bait). По моим исследованиям, в Java есть множество способов получить расширение файла, но все они требуют полного пути. Предполагается, что мой компилятор запускается из любого места на диске пользователя через терминал (CMD), поэтому я не думаю, что параметры Java полезны.

Вопрос: Как я могу отфильтровать расширение файла данного файла, если компилятор отклоняет источник, если это не .bait?

Исходный код, который я использую, довольно прост:

hook analizador = new hook (System.in);
analizador.RunLexer();

'hook' - это класс, а RunLexer () - метод лексического анализа. Код позволяет анализировать любой текстовый код. Для правила расширения я подумал об использовании регулярного выражения * .bait, как в:

hook analizador = new hook (new FileInputStream("*.bait"));
analizador.codigo();

и

InputStream input = new FileInputStream("*.bait");
hook analizador = new hook (input);

пока без удачи. Кто-нибудь может направить меня с этим? Объяснение ответа будет с благодарностью.

РЕДАКТИРОВАТЬ: Благодаря sepp2k и MeetTitan.

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

String arc = args[0];
if(arc.endsWith(".bait")){ //checks file extention
    File src = new File(arc); //created just to use exists()
    if(src.exists()){
        FileReader fr = new FileReader(arc); //used instead of System.in
        hook analizador = new hook(fr);
    } else System.out.println("File not found");
} else System.out.println("Invalid filetype");

Что касается способа использования программы, используя терминал (CMD)

java hook file.bait

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

Надеюсь, это кому-нибудь пригодится, и еще раз спасибо, sepp2k и MeetTitan!

1 Ответ

0 голосов
/ 08 ноября 2018

Почему ты не можешь сделать что-то подобное?

//this method takes a String and returns a substring containing the characters between the last occurrence of '.' and the end of the String
//For example, getExtension("test/your.file.bait"); will return "bait".
public static String getExtension(String fileNameOrPath) {
    return fileNameOrPath.substring(fileNameOrPath.lastIndexOf('.')+1);
}

//this method compares equality of "bait" and the returned extension from our other method
public static boolean isBait(String fileNameOrPath) {
     return "bait".equals(getExtension(fileNameOrPath));
}

Вы можете использовать isBait(String) для любого пути, относительного или абсолютного, или имени файла.

Вы также можете просто использовать String.endsWith(String). Вот так:

public static boolean isBait(String str) {
    return str.endsWith(".bait");
}

EDIT Чтобы получить список всех файлов в папке с определенным расширением, вы должны использовать FilenameFilter с File.listFiles()

Вот так:

File dir = new File("path/to/folder");
File[] baitFiles = dir.listFiles(new FilenameFilter() {
    public boolean accept(File dir, String name) {
        return name.toLowerCase().endsWith(".bait");
    }
});

РЕДАКТИРОВАТЬ для рекурсии через КАЖДУЮ подпапку и получать только определенные файлы:

public static List<File> recurseGetBait(File dir) { //need method for recursion
    List<File> baitFilesList = new ArrayList<>(); //make a new ArrayList that we will populate and return
    File[] baitFiles = dir.listFiles(new FilenameFilter() { //get all bait files with previously shown snippet
        public boolean accept(File dir, String name) {
            return name.toLowerCase().endsWith(".bait");
        }
    });
    for(File baitFile : baitFiles) {
        baitFilesList.add(baitFile); //add every file from baitFiles to baitFilesList
    }
    String[] dirs = file.list(new FilenameFilter() { //get all subfolders of current folder
        public boolean accept(File dir, String name) {
            return new File(dir, name).isDirectory();
        }
    });
    for(File dir : dirs) { //iterate over all subfolders
        List<File> returned = recursiveGetBait(dir); //run this same method on this subfolder (which will recurse until there are no sub folders)
        baitFilesList.addAll(returned); // add all of the previously returned bait files to baitFilesList so we populate and return
    }
    return baitFilesList; //either returns our list to the previous recurse or returns the fully built list to our original caller
}
...