我有一个像这样的字节写的文件
\r\x00\x00\x00\xd0{"a": "test"}
具有以下字节
[13, 0, 0, 0, -48, 123, 34, 97, 34, 58, 32, 34, 116, 101, 115, 116, 34, 125]
当这个文件被读入Java时,我得到了所有东西的转义
\\r\\x00\\x00\\x00\\xd0{"a": "test"}
当我对此字符串执行.getBytes()
时,我得到了
[92, 114, 92, 120, 48, 48, 92, 120, 48, 48, 92, 120, 48, 48, 92, 120, 100, 48, 123, 34, 97, 34, 58, 32, 34, 116, 101, 115, 116, 34, 125]
我必须将字符串转换为有效字节,遗憾的是我无法更改文件的读取方式。我知道在Python中,你打开一个'rb'
模式的文件,你很高兴。如果java具有该能力,我就无法使用它。
简而言之,我如何将字符串Java读取转换为写入文件的原始字节数组?
很抱歉,如果这个问题很简单,那么对于Java来说我是如此的绿色。
编辑:所以我认为我的问题与提议的“重复问题”链接不同。它没有取得java字符串中的每个字面值并将其转换回字节。 java中的字符串已被读者转义。 \x00
现在是\\x00
,它与字节值不同。所以我想我需要某种方法来取消字符串?
在十六进制编辑器中查看的文件
0000000: 5c72 5c78 3030 5c78 3030 5c78 3030 5c78 \r\x00\x00\x00\x
0000010: 6430 7b22 6122 3a20 2274 6573 7422 7d0a d0{"a": "test"}.
在十六进制编辑器中查看java的字符串
0000000: 5c5c 725c 5c78 3030 5c5c 7830 305c 5c78 \\r\\x00\\x00\\x
0000010: 3030 5c5c 7864 307b 2261 223a 2022 7465 00\\xd0{"a": "te
0000020: 7374 227d 0a st"}.
答案 0 :(得分:2)
在Java中,您必须解释输入字符串以获取所需的字节值。
我编写了一个解释输入字符串的Java应用程序。
这里是输入字符串:
\r\x00\x00\x00\xd0{"a": "test"}
结果如下:
[13, 0, 0, 0, -48, 34, 97, 34, 58, 32, 34, 116, 101, 115, 116, 34, 125]
这是代码。您可能需要稍微修改一下代码来处理您没有提出问题的案例。
package com.ggl.testing;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ConvertBytes implements Runnable {
private String fileName;
public static void main(String[] args) {
new ConvertBytes("bytes.txt").run();
}
public ConvertBytes(String fileName) {
this.fileName = fileName;
}
@Override
public void run() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(getClass()
.getResourceAsStream(fileName)));
String line = "";
while ((line = br.readLine()) != null) {
processLine(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void processLine(String line) {
String[] parts = line.split("(?=\\\\)");
List<Byte> byteList = new ArrayList<Byte>();
for (int i = 0; i < parts.length; i++) {
if (parts[i].equals("")) {
continue;
} else {
byteList.addAll(getValue(parts[i]));
}
}
Byte[] bytes = byteList.toArray(new Byte[byteList.size()]);
System.out.println(Arrays.toString(bytes));
}
private List<Byte> getValue(String s) {
List<Byte> byteList = new ArrayList<Byte>();
if (s.startsWith("\\x")) {
int value = Integer.valueOf(s.substring(2, 4), 16);
if (value > 127) {
value = value - 256;
}
byteList.add(Byte.valueOf((byte) value));
if (s.length() > 4) {
byteList.addAll(getAsciiValue(s.substring(4)));
}
} else if (s.equals("\\r")) {
byteList.add(Byte.valueOf((byte) 13));
} else if (s.equals("\\t")) {
byteList.add(Byte.valueOf((byte) 9));
} else {
byteList.addAll(getAsciiValue(s));
}
return byteList;
}
private List<Byte> getAsciiValue(String s) {
List<Byte> byteList = new ArrayList<Byte>();
for (int i = 0; i < s.length(); i++) {
int value = (int) s.charAt(i);
byteList.add(Byte.valueOf((byte) value));
}
return byteList;
}
}
bytes.txt文件必须与Java应用程序位于同一目录中。
答案 1 :(得分:1)
看起来你必须解析&#34; String&#34;排队。
我会有一张转义字符的地图(&#39; \ r&#39;,&#39; \ n&#39;,&#39; \ b&#39;等等...)
private static Map<String, Byte> escapedCharacters;
static {
escapedCharacters = new HashMap<>();
escapedCharacters.put("\\b", (byte)'\b');
escapedCharacters.put("\\f", (byte)'\f');
escapedCharacters.put("\\n", (byte)'\n');
escapedCharacters.put("\\r", (byte)'\r');
escapedCharacters.put("\\t", (byte)'\t');
// Add more if needed
};
然后以下处理您的文件:
public static void main(String[] args) throws Exception {
String myFile = "PathToYourFile";
// Read your file in
List<String> myFileLines = Files.readAllLines(Paths.get(myFile));
// List to hold all the lines as translated bytes
List<byte[]> myFileLinesAsBytes = new ArrayList<>();
for (String line : myFileLines) {
myFileLinesAsBytes.add(translateEscapedBytes(line));
}
// Displays all translated lines
for (byte[] byteLine : myFileLinesAsBytes) {
System.out.println(Arrays.toString(byteLine));
}
System.out.println();
}
private static byte[] translateEscapedBytes(String line) throws UnsupportedEncodingException {
List<Byte> translatedBytes = new ArrayList<>();
for (int i = 0; i < line.length();) {
if (line.charAt(i) == '\\') { // Escaped byte
String escapedByte = line.substring(i, i + 2);
if (escapedByte.endsWith("x")) { // Hexidecimal number
escapedByte = line.substring(i + 2, i + 4); // + 4 to get the two numbers after \x
translatedBytes.add(hexStringToByte(escapedByte));
i += 4;
} else { // Escaped character
translatedBytes.add(escapedCharacters.get(escapedByte));
i += 2;
}
} else { // Non Escapted Character
translatedBytes.add((byte)(line.charAt(i)));
i++;
}
}
// Copy List to actual byte[] to return
byte[] result = new byte[translatedBytes.size()];
for (int i = 0; i < translatedBytes.size(); i++) {
result[i] = translatedBytes.get(i);
}
return result;
}
private static byte hexStringToByte(String s) {
return (byte) ((Character.digit(s.charAt(0), 16) << 4) + Character.digit(s.charAt(1), 16));
}
translatedEscapedBytes()
寻找&#34; \&#34;字符串中的字符并标识与下一个字符组合的字符,您将拥有一个转义字符。如果转义字符是\ x,那么您知道接下来的两个数字是十六进制数字,需要转换为字节(hexStringToByte(String s)
),否则使用转义字符映射将转义字符转换为字节。所有其他字符都被视为非转义字符,只是转换为字节值。
结果(使用您提供的数据):
答案 2 :(得分:0)
在Java中读取文件时,您没有获得“所有转义”。为什么你这么想?转换为字节显示String
正好包含十六进制编辑器在文件中显示的内容。换句话说,
92,114,92,120,48,48,92,120,48,48,92,120,48,48,92,120(十进制)
与
相同5c72 5c78 3030 5c78 3030 5c78 3030 5c78(hex)
如果要解码文件中的转义序列,则需要编写一些代码来处理它们;这不是字符编码问题。