使用 JSmooth 包装 .jar 时字符串搜索中断
String search breaking when wrapping .jar with JSmooth
我遇到了一个奇怪的问题。我有一个 java 小程序可以过滤 Minecraft 日志文件,使它们更易于阅读。在这些日志的每一行中,字符“§”通常有多个实例,returns 十六进制值 FFFD。
我正在使用以下方法过滤掉这个字符(以及它后面的字符):
currentLine = currentLine.replaceAll("\uFFFD.", "");
现在,当我通过 NetBeans 运行 程序时,它运行良好。我的行输出如下所示:
CxndyAnnie: Mhm
CxndyAnnie: Sorry
但是当我构建 .jar 文件并使用 JSmooth 将其包装到 .exe 文件中时,当我 运行 .exe 时,该字符不再被过滤掉,我的行看起来像这样:
§e§7[§f§7] §1§nCxndyAnnie§e: Mhm
§e§7[§f§7] §1§nCxndyAnnie§e: Sorry
(注意:显示额外的方括号和 $65 是因为它们的过滤取决于特殊字符,并且它后面的字符首先被删除)
知道为什么在通过 JSmooth 后它不再有效吗?是否有不同的方法来进行文本替换以保留其功能?
顺便说一下,我也尝试使用
删除这个字符
currentLine = currentLine.replaceAll("§.", "");
但这在 Netbeans 和 .exe 中都不起作用。
我将继续并通过下面的完整方法:
public static String[] filterLines(String[] allLines, String filterType, Boolean timeStamps) throws IOException {
String currentLine = null;
FileWriter saveFile = new FileWriter("readable.txt");
String heading;
String string1 = "[L]";
String string2 = "[A]";
String string3 = "[G]";
if (filterType.equals(string1)) {
heading = "LOCAL CHAT LOGS ONLY \r\n\r\n";
}
else if (filterType.equals(string2)) {
heading = "ADVERTISING CHAT LOGS ONLY \r\n\r\n";
}
else if (filterType.equals(string3)) {
heading = "GLOBAL CHAT LOGS ONLY \r\n\r\n";
}
else {
heading = "CHAT LINES CONTAINING \"" + filterType + "\" \r\n\r\n";
}
saveFile.write(heading);
for (int i = 0; i < allLines.length; i++) {
if ((allLines[i] != null ) && (allLines[i].contains(filterType))) {
currentLine = allLines[i];
if (!timeStamps) {
currentLine = currentLine.replaceAll("\[..:..:..\].", "");
}
currentLine = currentLine.replaceAll("\[Client thread/INFO\]:.", "");
currentLine = currentLine.replaceAll("\[CHAT\].", "");
currentLine = currentLine.replaceAll("\uFFFD.", "");
currentLine = currentLine.replaceAll("\[A\].", "");
currentLine = currentLine.replaceAll("\[L\].", "");
currentLine = currentLine.replaceAll("\[G\].", "");
currentLine = currentLine.replaceAll("\[\$..\].", "");
currentLine = currentLine.replaceAll(".>", ":");
currentLine = currentLine.replaceAll("\[\0\].", "");
saveFile.write(currentLine + "\r\n");
//System.out.println(currentLine);
}
}
saveFile.close();
ProcessBuilder openFile = new ProcessBuilder("Notepad.exe", "readable.txt");
openFile.start();
return allLines;
}
最终编辑
以防万一有人偶然发现这个问题并需要知道最后是什么起作用了,这是我从文件中提取行并重新编码使其起作用的代码片段:
BufferedReader fileLines;
fileLines = new BufferedReader(new FileReader(file));
String[] allLines = new String[numLines];
int i=0;
while ((line = fileLines.readLine()) != null) {
byte[] bLine = line.getBytes();
String convLine = new String(bLine, Charset.forName("UTF-8"));
allLines[i] = convLine;
i++;
}
我在过去的 minecroft 日志中也遇到过这样的问题,我不记得确切的细节,但问题归结为文件格式问题,其中 UTF8 编码工作正常,但其他一些文本编码包括系统默认值无法正常工作。
第一个:
确保在从文件中读取 byteArray 时指定 UTF8 编码,以便 allLines
包含正确的信息,如下所示:
Path fileLocation = Paths.get("C:/myFileLocation/logs.txt");
byte[] data = Files.readAllBytes(fileLocation);
String allLines = new String(data , Charset.forName("UTF-8"));
第二个:
使用 \uFFFD
是行不通的,因为 \uFFFD
仅用于替换值未知或无法在 Unicode 中表示的传入字符。
但是,如果您使用了正确的编码(在我的第一点中显示),则 \uFFFD
不是必需的,因为值 § 在 unicode 中是已知的,因此您可以简单地使用
currentLine.replaceAll("§", "");
或者专门为该字符使用实际的 unicode 字符串 U+00A7
就像这样
currentLine.replaceAll("\u00A7", "");
或者在您的代码中同时使用这两行。
我遇到了一个奇怪的问题。我有一个 java 小程序可以过滤 Minecraft 日志文件,使它们更易于阅读。在这些日志的每一行中,字符“§”通常有多个实例,returns 十六进制值 FFFD。
我正在使用以下方法过滤掉这个字符(以及它后面的字符):
currentLine = currentLine.replaceAll("\uFFFD.", "");
现在,当我通过 NetBeans 运行 程序时,它运行良好。我的行输出如下所示:
CxndyAnnie: Mhm
CxndyAnnie: Sorry
但是当我构建 .jar 文件并使用 JSmooth 将其包装到 .exe 文件中时,当我 运行 .exe 时,该字符不再被过滤掉,我的行看起来像这样:
§e§7[§f§7] §1§nCxndyAnnie§e: Mhm
§e§7[§f§7] §1§nCxndyAnnie§e: Sorry
(注意:显示额外的方括号和 $65 是因为它们的过滤取决于特殊字符,并且它后面的字符首先被删除)
知道为什么在通过 JSmooth 后它不再有效吗?是否有不同的方法来进行文本替换以保留其功能?
顺便说一下,我也尝试使用
删除这个字符currentLine = currentLine.replaceAll("§.", "");
但这在 Netbeans 和 .exe 中都不起作用。
我将继续并通过下面的完整方法:
public static String[] filterLines(String[] allLines, String filterType, Boolean timeStamps) throws IOException {
String currentLine = null;
FileWriter saveFile = new FileWriter("readable.txt");
String heading;
String string1 = "[L]";
String string2 = "[A]";
String string3 = "[G]";
if (filterType.equals(string1)) {
heading = "LOCAL CHAT LOGS ONLY \r\n\r\n";
}
else if (filterType.equals(string2)) {
heading = "ADVERTISING CHAT LOGS ONLY \r\n\r\n";
}
else if (filterType.equals(string3)) {
heading = "GLOBAL CHAT LOGS ONLY \r\n\r\n";
}
else {
heading = "CHAT LINES CONTAINING \"" + filterType + "\" \r\n\r\n";
}
saveFile.write(heading);
for (int i = 0; i < allLines.length; i++) {
if ((allLines[i] != null ) && (allLines[i].contains(filterType))) {
currentLine = allLines[i];
if (!timeStamps) {
currentLine = currentLine.replaceAll("\[..:..:..\].", "");
}
currentLine = currentLine.replaceAll("\[Client thread/INFO\]:.", "");
currentLine = currentLine.replaceAll("\[CHAT\].", "");
currentLine = currentLine.replaceAll("\uFFFD.", "");
currentLine = currentLine.replaceAll("\[A\].", "");
currentLine = currentLine.replaceAll("\[L\].", "");
currentLine = currentLine.replaceAll("\[G\].", "");
currentLine = currentLine.replaceAll("\[\$..\].", "");
currentLine = currentLine.replaceAll(".>", ":");
currentLine = currentLine.replaceAll("\[\0\].", "");
saveFile.write(currentLine + "\r\n");
//System.out.println(currentLine);
}
}
saveFile.close();
ProcessBuilder openFile = new ProcessBuilder("Notepad.exe", "readable.txt");
openFile.start();
return allLines;
}
最终编辑
以防万一有人偶然发现这个问题并需要知道最后是什么起作用了,这是我从文件中提取行并重新编码使其起作用的代码片段:
BufferedReader fileLines;
fileLines = new BufferedReader(new FileReader(file));
String[] allLines = new String[numLines];
int i=0;
while ((line = fileLines.readLine()) != null) {
byte[] bLine = line.getBytes();
String convLine = new String(bLine, Charset.forName("UTF-8"));
allLines[i] = convLine;
i++;
}
我在过去的 minecroft 日志中也遇到过这样的问题,我不记得确切的细节,但问题归结为文件格式问题,其中 UTF8 编码工作正常,但其他一些文本编码包括系统默认值无法正常工作。
第一个:
确保在从文件中读取 byteArray 时指定 UTF8 编码,以便 allLines
包含正确的信息,如下所示:
Path fileLocation = Paths.get("C:/myFileLocation/logs.txt");
byte[] data = Files.readAllBytes(fileLocation);
String allLines = new String(data , Charset.forName("UTF-8"));
第二个:
使用 \uFFFD
是行不通的,因为 \uFFFD
仅用于替换值未知或无法在 Unicode 中表示的传入字符。
但是,如果您使用了正确的编码(在我的第一点中显示),则 \uFFFD
不是必需的,因为值 § 在 unicode 中是已知的,因此您可以简单地使用
currentLine.replaceAll("§", "");
或者专门为该字符使用实际的 unicode 字符串 U+00A7
就像这样
currentLine.replaceAll("\u00A7", "");
或者在您的代码中同时使用这两行。