|
27 | 27 | import java.io.*; |
28 | 28 | import java.lang.reflect.*; |
29 | 29 | import java.net.*; |
| 30 | +import java.nio.charset.StandardCharsets; |
30 | 31 | import java.text.NumberFormat; |
31 | 32 | import java.util.*; |
32 | 33 | import java.util.regex.*; |
@@ -4534,32 +4535,6 @@ public void run() { |
4534 | 4535 | } |
4535 | 4536 |
|
4536 | 4537 |
|
4537 | | - |
4538 | | - ////////////////////////////////////////////////////////////// |
4539 | | - |
4540 | | - // EXTENSIONS |
4541 | | - |
4542 | | - |
4543 | | - /** |
4544 | | - * Get the compression-free extension for this filename. |
4545 | | - * @param filename The filename to check |
4546 | | - * @return an extension, skipping past .gz if it's present |
4547 | | - */ |
4548 | | - static public String checkExtension(String filename) { |
4549 | | - // Don't consider the .gz as part of the name, createInput() |
4550 | | - // and createOuput() will take care of fixing that up. |
4551 | | - if (filename.toLowerCase().endsWith(".gz")) { |
4552 | | - filename = filename.substring(0, filename.length() - 3); |
4553 | | - } |
4554 | | - int dotIndex = filename.lastIndexOf('.'); |
4555 | | - if (dotIndex != -1) { |
4556 | | - return filename.substring(dotIndex + 1).toLowerCase(); |
4557 | | - } |
4558 | | - return null; |
4559 | | - } |
4560 | | - |
4561 | | - |
4562 | | - |
4563 | 4538 | ////////////////////////////////////////////////////////////// |
4564 | 4539 |
|
4565 | 4540 | // DATA I/O |
@@ -4980,6 +4955,156 @@ public PFont createFont(String name, float size, |
4980 | 4955 | // } |
4981 | 4956 |
|
4982 | 4957 |
|
| 4958 | + ////////////////////////////////////////////////////////////// |
| 4959 | + |
| 4960 | + // LISTING DIRECTORIES |
| 4961 | + |
| 4962 | + |
| 4963 | + public String[] listPaths(String path, String... options) { |
| 4964 | + File[] list = listFiles(path, options); |
| 4965 | + |
| 4966 | + int offset = 0; |
| 4967 | + for (String opt : options) { |
| 4968 | + if (opt.equals("relative")) { |
| 4969 | + if (!path.endsWith(File.pathSeparator)) { |
| 4970 | + path += File.pathSeparator; |
| 4971 | + } |
| 4972 | + offset = path.length(); |
| 4973 | + break; |
| 4974 | + } |
| 4975 | + } |
| 4976 | + String[] outgoing = new String[list.length]; |
| 4977 | + for (int i = 0; i < list.length; i++) { |
| 4978 | + // as of Java 1.8, substring(0) returns the original object |
| 4979 | + outgoing[i] = list[i].getAbsolutePath().substring(offset); |
| 4980 | + } |
| 4981 | + return outgoing; |
| 4982 | + } |
| 4983 | + |
| 4984 | + |
| 4985 | + public File[] listFiles(String path, String... options) { |
| 4986 | + File file = new File(path); |
| 4987 | + // if not an absolute path, make it relative to the sketch folder |
| 4988 | + if (!file.isAbsolute()) { |
| 4989 | + file = sketchFile(path); |
| 4990 | + } |
| 4991 | + return listFiles(file, options); |
| 4992 | + } |
| 4993 | + |
| 4994 | + |
| 4995 | + // "relative" -> no effect with the Files version, but important for listPaths |
| 4996 | + // "recursive" |
| 4997 | + // "extension=js" or "extensions=js|csv|txt" (no dot) |
| 4998 | + // "directories" -> only directories |
| 4999 | + // "files" -> only files |
| 5000 | + // "hidden" -> include hidden files (prefixed with .) disabled by default |
| 5001 | + static public File[] listFiles(File base, String... options) { |
| 5002 | + boolean recursive = false; |
| 5003 | + String[] extensions = null; |
| 5004 | + boolean directories = true; |
| 5005 | + boolean files = true; |
| 5006 | + boolean hidden = false; |
| 5007 | + |
| 5008 | + for (String opt : options) { |
| 5009 | + if (opt.equals("recursive")) { |
| 5010 | + recursive = true; |
| 5011 | + } else if (opt.startsWith("extension=")) { |
| 5012 | + extensions = new String[] { opt.substring(10) }; |
| 5013 | + } else if (opt.startsWith("extensions=")) { |
| 5014 | + extensions = split(opt.substring(10), ','); |
| 5015 | + } else if (opt.equals("files")) { |
| 5016 | + directories = false; |
| 5017 | + } else if (opt.equals("directories")) { |
| 5018 | + files = false; |
| 5019 | + } else if (opt.equals("hidden")) { |
| 5020 | + hidden = true; |
| 5021 | + } else if (opt.equals("relative")) { |
| 5022 | + // ignored |
| 5023 | + } else { |
| 5024 | + throw new RuntimeException(opt + " is not a listFiles() option"); |
| 5025 | + } |
| 5026 | + } |
| 5027 | + |
| 5028 | + if (extensions != null) { |
| 5029 | + for (int i = 0; i < extensions.length; i++) { |
| 5030 | + extensions[i] = "." + extensions[i]; |
| 5031 | + } |
| 5032 | + } |
| 5033 | + |
| 5034 | + if (!files && !directories) { |
| 5035 | + // just make "only files" and "only directories" mean... both |
| 5036 | + files = true; |
| 5037 | + directories = true; |
| 5038 | + } |
| 5039 | + |
| 5040 | + if (!base.canRead()) { |
| 5041 | + return null; |
| 5042 | + } |
| 5043 | + |
| 5044 | + List<File> outgoing = new ArrayList<>(); |
| 5045 | + listFilesImpl(base, recursive, extensions, hidden, directories, files, outgoing); |
| 5046 | + return outgoing.toArray(new File[0]); |
| 5047 | + } |
| 5048 | + |
| 5049 | + |
| 5050 | + static void listFilesImpl(File folder, boolean recursive, |
| 5051 | + String[] extensions, boolean hidden, |
| 5052 | + boolean directories, boolean files, |
| 5053 | + List<File> list) { |
| 5054 | + File[] items = folder.listFiles(); |
| 5055 | + if (items != null) { |
| 5056 | + for (File item : items) { |
| 5057 | + String name = item.getName(); |
| 5058 | + if (!hidden && name.charAt(0) == '.') { |
| 5059 | + continue; |
| 5060 | + } |
| 5061 | + if (item.isDirectory()) { |
| 5062 | + if (recursive) { |
| 5063 | + listFilesImpl(item, recursive, extensions, hidden, directories, files, list); |
| 5064 | + } |
| 5065 | + if (directories) { |
| 5066 | + list.add(item); |
| 5067 | + } |
| 5068 | + } else if (files) { |
| 5069 | + if (extensions == null) { |
| 5070 | + list.add(item); |
| 5071 | + } else { |
| 5072 | + for (String ext : extensions) { |
| 5073 | + if (item.getName().toLowerCase().endsWith(ext)) { |
| 5074 | + list.add(item); |
| 5075 | + } |
| 5076 | + } |
| 5077 | + } |
| 5078 | + } |
| 5079 | + } |
| 5080 | + } |
| 5081 | + } |
| 5082 | + |
| 5083 | + |
| 5084 | + |
| 5085 | + ////////////////////////////////////////////////////////////// |
| 5086 | + |
| 5087 | + // EXTENSIONS |
| 5088 | + |
| 5089 | + |
| 5090 | + /** |
| 5091 | + * Get the compression-free extension for this filename. |
| 5092 | + * @param filename The filename to check |
| 5093 | + * @return an extension, skipping past .gz if it's present |
| 5094 | + */ |
| 5095 | + static public String checkExtension(String filename) { |
| 5096 | + // Don't consider the .gz as part of the name, createInput() |
| 5097 | + // and createOuput() will take care of fixing that up. |
| 5098 | + if (filename.toLowerCase().endsWith(".gz")) { |
| 5099 | + filename = filename.substring(0, filename.length() - 3); |
| 5100 | + } |
| 5101 | + int dotIndex = filename.lastIndexOf('.'); |
| 5102 | + if (dotIndex != -1) { |
| 5103 | + return filename.substring(dotIndex + 1).toLowerCase(); |
| 5104 | + } |
| 5105 | + return null; |
| 5106 | + } |
| 5107 | + |
4983 | 5108 |
|
4984 | 5109 | ////////////////////////////////////////////////////////////// |
4985 | 5110 |
|
|
0 commit comments