Я использую следующие два метода: toPrintable для преобразования исходной строки в печатную строку, fromPrintable, чтобы преобразовать ее обратно.
Я включил знак процента в преобразование, потому что иногда я могу использовать преобразованную строку как часть строки формата, и это предотвращает путаницу с исходными знаками процента с символами процента форматирования.
/**
* Converts a string containing control characters to a printable string.
* Control characters are replaced by \hh, were hh is the hexadecimal
* representation. The backslash and percent sign are also converted to
* hexadecimal.
*
* @param raw
* The input string to be converted.
*
* @return a string representing this instance.
*/
public static String toPrintable(final String raw) {
final StringBuilder sb = new StringBuilder();
if (raw == null) {
return "";
}
for (final char c : raw.toCharArray()) {
if ((c <= 31) || (c == 127) || (c == '\\') || (c == '%')) {
sb.append(String.format("\\%02X", (int) c));
} else {
sb.append(c);
}
}
/*
* If the last character is a space, convert it to hexadecimal, to avoid
* loosing it.
*/
if (raw.endsWith(" ")) {
sb.setLength(sb.length() - 1);
sb.append("\\20");
}
return sb.toString();
}
/**
* Converts a string containing coded control characters to the original
* string. Control characters are represented by \hh, were hh is the
* hexadecimal representation. The backslash is also represented as
* hexadecimal.
*
* @param t
* The converted string to be restored.
* @return The original string.
*/
public static String fromPrintable(final String t) {
final StringBuilder sb = new StringBuilder();
final int tLength = t.length();
boolean error = false;
for (int i = 0; i < tLength; i++) {
if (t.charAt(i) == '\\') {
if ((i + 1) < tLength) {
if (t.charAt(i + 1) == '\\') {
sb.append(t.charAt(i++));
} else {
if (i < (tLength - 2)) {
final int v1 = validHexDigits.indexOf(t
.charAt(i + 1));
final int v2 = validHexDigits.indexOf(t
.charAt(i + 2));
i += 2;
if ((v1 < 0) || (v2 < 0)) {
error = true;
} else {
final char cc = (char) ((validHexValues[v1] << 4) + validHexValues[v2]);
sb.append(cc);
}
} else {
error = true;
}
}
} else {
error = true;
}
} else {
sb.append(t.charAt(i));
}
}
if (error) {
log.warn("fromPrintable: Invalid input [%s]", t);
}
return sb.toString();
}
Всегда лучше читать двоичный файл в байтах, а не как строку напрямую. Позже вы можете преобразовать байты в строку String –
. Вам нужно выяснить, каковы эти символы * на самом деле. Они четко обозначают * не * точки, поскольку точки видны. Отправьте шестнадцатеричный дамп соответствующего раздела файла и сообщите нам, какую кодировку вы используете. –
Я не думаю, что они «точки», я думаю, что они не являются печатными символами. Что такое шестнадцатеричные значения? – MadProgrammer