java - 文件到字节数组的转换实际上是如何工作的?
问题描述
我有一个代码来打印文件的所有字节:
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 的字符串时,必须提供这个缺失和相关的字符集。
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)。
对于真正的二进制数据,只有字节。
推荐阅读
- azure - Azure AD Connect 预配代理日志中出现错误的超慢用户预配
- azure-devops - 执行发布质量门任务时 Azure devops 中的 SonarQube 错误
- python - 获取错误编解码器无法对位置 8-13 中的字符进行编码:字符映射到
- c# - HttpClient - 请求被取消 - 超时 100 秒
- ios - 从 PHAsset 中检索原始图像(或视频)
- python - 为什么 MOD_SHIFT 事件键在 PYGAME Mac 中不起作用
- javascript - 每次用户单击(突出显示)输入字段以在其中输入值时,我都想记录一个操作。我能做些什么来实现这样的功能?
- r - R 中的 xgboost 提供了意想不到的预测
- hibernate - JPA SqlResultSetMapping to pojo,属性中具有复杂对象
- python - PyParsing:如果不是关键字则解析