Исключить расширения файлов для компилятора на основе Java?
Я обычно нахожу обходной путь для проблем, но на этот раз я не могу найти его.
Я делаю компилятор для самостоятельно разработанного языка с использованием 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 ответ
Почему ты не можешь сделать что-то подобное?
//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");
}
РЕДАКТИРОВАТЬ Чтобы получить список всех файлов в папке с определенным расширением, вы должны использовать 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
}