我有一个代码可以打印文件的所有字节:
String txtDocumentName = "data.txt";
File file = new File(txtDocumentName);
byte[] bytes = Files.readAllBytes(file.toPath());
System.out.println("bytes.length: " + bytes.length);
System.out.println("bytes:");
for (byte currentByte: bytes) {
System.out.println(currentByte);
}
如果我有一个data.txt
文档内容:
abc
,然后它会打印:
bytes.length: 3
bytes:
97
98
99
其中字节长度为3,因为我有3个字符。 97表示“a”字符的ASCII码,98表示“b”字符的ASCII码,等等
另外,如果我有一个包含俄语内容的 data.txt
文档:
собака
,然后它会打印:
bytes.length: 12
bytes:
-47
-127
-48
-66
-48
-79
-48
-80
-48
-70
-48
-80
现在我不明白它实际上做了什么)
你能解释一下吗?
PS:собака在英语中的意思是狗
如果您也能解释一下这个技巧如何处理图像文件和视频文件,我会很高兴
最佳答案
文本字节很特殊,因为缺少一个信息:字节使用什么编码/字符集?在第一种情况下,ASCII 的一些超集。在俄语的第二种情况下,它不是单字节编码(否则长度将为 6)。
因此,两个文本都可以采用 UTF-8 格式,对于每个西里尔字母,都使用两个具有高位设置的字节(因此为“负”)。当从 java 的字符串转换或转换为 java 的字符串时,必须提供这一缺失的和关联的字符集。
byte[] bytes = ...;
String s = new String(bytes, StandardCharsets.UTF_8);
bytes = s.getBytes(StandardCharsets.UTF_8);
对于俄语,您可以在 Windows-1251 中编写文本:
Path cyrPath = file.toPath().resolveSibling("cp1251.txt");
Files.write(cyrPath, s, Charset.from("Windows-1251"));
6 字节,在俄语 Windows 上可读。
如果您有纯二进制、非文本数据,切勿使用 String。由于 String 始终需要在 byte[]
之间进行转换,因此可能会出错(并非所有字节数组都是有效的 UTF-8)。
对于真正的二进制数据,只有字节。
关于java - 文件到字节数组的转换实际上是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59935273/