我的程序显示从文本文件中读取的元素。文本文件将存储在包含.java
和.class
文件的包文件夹中的文件夹中,以便它们可以嵌入到jar中。
我正在尝试让应用程序在两种情况下正确读取文本文件
目前我可以做一点没有问题,但是代码使用File
进行读取,因为我看到如何使用Jars使用InputStream
。
适用于IDE的功能
public void loadWidgets() {
ArrayList<String> results = new ArrayList<>();
String dir = new File("").getAbsolutePath() + "/src/Creator/textFiles/widgets/;
System.out.println(dir);
getWidgetFiles(dir, results);
results.stream().forEach((s) -> {
readFile(s); // given a string and it opens the file using a Scanner
});
updateWidgetVariables(); // gui updates
}
public void getWidgetFiles(String dirName, ArrayList<String> filePaths) {
File directory = new File(dirName);
File[] files = directory.listFiles();
for (File file : files) {
if (file.isFile()) {
filePaths.add(file.getName() + "," + file.getAbsolutePath());
} else if (file.isDirectory()) {
getWidgetFiles(file.getAbsolutePath(), filePaths);
}
}
}
所以我有一堆按小部件类型组织的文本文件,所以我正在运行/ widgets /目录来查找所有文本文件。
我遇到的问题是我如何浏览Jar的目录和文件?它们可以转换为文件,还是读成字符串?
我从这个question获得了此代码,它可以读取文件,但我不知道如何使用new Scanner(file);
代码打开它们
CodeSource src = WidgetPanel.class.getProtectionDomain().getCodeSource();
try {
System.out.println("Inside try");
List<String> list = new ArrayList<>();
if (src != null) {
URL jar = src.getLocation();
ZipInputStream zip = new ZipInputStream(jar.openStream());
ZipEntry ze = null;
System.out.println(jar.getPath());
System.out.println(zip.getNextEntry());
while ((ze = zip.getNextEntry()) != null) {
String entryName = ze.getName();
System.out.println("Entry name: " + entryName);
if (entryName.startsWith("Creator/textFiles/widgets") && entryName.endsWith(".txt")) {
list.add(entryName);
System.out.println("Added name: " + entryName);
}
}
list.stream().forEach((s) -> {
readFile(s);
});
updateWidgetVariables();
} else {
System.out.println("Src null");
}
}catch (IOException e) {
System.out.println(e.getMessage());
}
答案 0 :(得分:0)
尝试获取与您的来源相关联的FileSystem
;事情变得非常简单。以下是如何以文本形式读取给定文件系统中的所有文件的说明:
private static final BiPredicate<Path, BasicFileAttributes> FILES
= (path, attrs) -> attrs.isRegularFile();
private static void readAllFilesAsText(final List<Path> paths)
throws IOException
{
for (final Path path: paths)
try (
final Stream<String> stream = Files.lines(path);
) {
stream.forEach(System.out::println);
}
}
private static List<Path> getAllFilesFromFileSystems(final FileSystem fs,
final String pathPrefix)
{
final Path baseDir = fs.getPath(pathPrefix);
try (
final Stream<Path> files = Files.find(baseDir, Integer.MAX_VALUE,
FILES);
) {
return files.collect(Collectors.toList());
}
}
为什么循环的“旧式”和“新式”lambdas的混合:这是因为lambdas只是不处理已检查的异常......这意味着你必须这样做。有关解决方法,请参阅here。
但这里的要点是能够从你的来源创建FileSystem
,你可以做到;是的,你可以这样阅读罐子。请参阅here。
答案 1 :(得分:0)
我能够使用我已经拥有的功能找到解决方案。
我首先检查文本文件是否可以正常找到(从IDE运行)。如果发现文件未找到异常,则设置ide = false,以便它尝试从jar中读取。
public void loadWidgets() {
boolean ide = true;
String path = "textFiles/widgets/";
ArrayList<String> results = new ArrayList<>();
String dir = new File("").getAbsolutePath() + "/src/Creator/" + path;
try {
getWidgetFiles(dir, results);
results.stream().forEach((s) -> {
readFile(s);
});
updateWidgetVariables();
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
ide = false;
}
if (!ide) {
CodeSource src = WidgetPanel.class.getProtectionDomain().getCodeSource();
try {
List<String> list = new ArrayList<>();
if (src != null) {
URL jar = src.getLocation();
ZipInputStream zip = new ZipInputStream(jar.openStream());
ZipEntry ze = null;
while ((ze = zip.getNextEntry()) != null) {
String entryName = ze.getName();
if (entryName.startsWith("Creator/textFiles/widgets") && entryName.endsWith(".txt")) {
// Wouldnt work until i added the "/" before the entryName
list.add("/"+ entryName);
System.out.println("Added name: " + entryName);
}
}
list.stream().forEach((s) -> {
readJarFile(s);
});
updateWidgetVariables();
} else {
System.out.println("Src null");
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
然后我创建了一个新的readFile函数,用于从Jar中读取
public void readJarFile(String result) {
String name = result.substring(result.lastIndexOf("/") + 1);
String entireWidget = "";
String line;
ArrayList<String> vars = new ArrayList<>();
int begin, end;
InputStream loc = this.getClass().getResourceAsStream(result);
try (Scanner scan = new Scanner(loc)) {
while (scan.hasNextLine()) {
line = scan.nextLine();
entireWidget += line;
while (line.contains("`%")) {
begin = line.indexOf("`%");
end = line.indexOf("%`") + 2;
vars.add(line.substring(begin, end));
//System.out.println("Variable added: " + line.substring(begin, end));
line = line.substring(end);
}
}
}
System.out.println(name + ": " + entireWidget);
Widget widget = new Widget(name, vars, entireWidget, result);
widgetList.put(name, widget);
}
这个答案大部分归功于question