为什么 "STRING".getBytes() 根据操作系统的不同而不同
why does "STRING".getBytes() work different according to the Operation System
我正在 运行 宁下面的代码,我从 "some_string".getBytes() 得到不同的结果,这取决于我是在 Windows 还是 Unix 中。任何字符串都会出现此问题(我尝试了一个非常简单的 ABC 和同样的问题。
查看控制台中打印的以下差异。
下面的代码使用 Java 7 进行了很好的测试。如果您完全复制它,它将 运行。
另外,请看下面两张图片中十六进制的区别。前两个图像显示了在 Windows 中创建的文件。您可以分别使用 ANSI 和 EBCDIC 查看十六进制值。第三张图片,黑色的,来自 Unix。您可以看到十六进制(-c 选项)和我认为是 EBCDIC 的可读字符。
所以,我的直接问题是:为什么这样的代码工作不同,因为我在这两种情况下都只使用 Java 7?我应该在某个地方检查任何特定的 属性 吗?也许,Windows 中的 Java 获得某种默认格式,而在 Unix 中它获得另一种默认格式。如果是这样,我必须检查或设置哪个 属性?
Unix 控制台:
$ ./java -cp /usr/test.jar test.mainframe.read.test.TestGetBytes
H = 76 - L
< wasn't found
Windows 控制台:
H = 60 - <
H1 = 69 - E
H2 = 79 - O
H3 = 77 - M
H4 = 62 - >
End of Message found
完整代码:
package test.mainframe.read.test;
import java.util.ArrayList;
public class TestGetBytes {
public static void main(String[] args) {
try {
ArrayList ipmMessage = new ArrayList();
ipmMessage.add(newLine());
//Windows Path
writeMessage("C:/temp/test_bytes.ipm", ipmMessage);
reformatFile("C:/temp/test_bytes.ipm");
//Unix Path
//writeMessage("/usr/temp/test_bytes.ipm", ipmMessage);
//reformatFile("/usr/temp/test_bytes.ipm");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static byte[] newLine() {
return "<EOM>".getBytes();
}
public static void writeMessage(String fileName, ArrayList ipmMessage)
throws java.io.FileNotFoundException, java.io.IOException {
java.io.DataOutputStream dos = new java.io.DataOutputStream(
new java.io.FileOutputStream(fileName, true));
for (int i = 0; i < ipmMessage.size(); i++) {
try {
int[] intValues = (int[]) ipmMessage.get(i);
for (int j = 0; j < intValues.length; j++) {
dos.write(intValues[j]);
}
} catch (ClassCastException e) {
byte[] byteValues = (byte[]) ipmMessage.get(i);
dos.write(byteValues);
}
}
dos.flush();
dos.close();
}
// reformat to U1014
public static void reformatFile(String filename)
throws java.io.FileNotFoundException, java.io.IOException {
java.io.FileInputStream fis = new java.io.FileInputStream(filename);
java.io.DataInputStream br = new java.io.DataInputStream(fis);
int h = br.read();
System.out.println("H = " + h + " - " + (char)h);
if ((char) h == '<') {// Check for <EOM>
int h1 = br.read();
System.out.println("H1 = " + h1 + " - " + (char)h1);
int h2 = br.read();
System.out.println("H2 = " + h2 + " - " + (char)h2);
int h3 = br.read();
System.out.println("H3 = " + h3 + " - " + (char)h3);
int h4 = br.read();
System.out.println("H4 = " + h4 + " - " + (char)h4);
if ((char) h1 == 'E' && (char) h2 == 'O' && (char) h3 == 'M'
&& (char) h4 == '>') {
System.out.println("End of Message found");
}
else{
System.out.println("EOM not found but < was found");
}
}
else{
System.out.println("< wasn't found");
}
}
}
您在调用 getBytes()
时未指定字符集,因此它使用底层平台的默认字符集(如果在 Java 启动时指定,则使用 Java 本身的默认字符集)。这在 String
documentation:
中说明
public byte[] getBytes()
Encodes this String into a sequence of bytes using the platform's default charset, storing the result into a new byte array.
getBytes()
有一个重载版本,可让您在代码中指定字符集。
public byte[] getBytes(Charset charset)
Encodes this String into a sequence of bytes using the given charset, storing the result into a new byte array.
我正在 运行 宁下面的代码,我从 "some_string".getBytes() 得到不同的结果,这取决于我是在 Windows 还是 Unix 中。任何字符串都会出现此问题(我尝试了一个非常简单的 ABC 和同样的问题。
查看控制台中打印的以下差异。
下面的代码使用 Java 7 进行了很好的测试。如果您完全复制它,它将 运行。
另外,请看下面两张图片中十六进制的区别。前两个图像显示了在 Windows 中创建的文件。您可以分别使用 ANSI 和 EBCDIC 查看十六进制值。第三张图片,黑色的,来自 Unix。您可以看到十六进制(-c 选项)和我认为是 EBCDIC 的可读字符。
所以,我的直接问题是:为什么这样的代码工作不同,因为我在这两种情况下都只使用 Java 7?我应该在某个地方检查任何特定的 属性 吗?也许,Windows 中的 Java 获得某种默认格式,而在 Unix 中它获得另一种默认格式。如果是这样,我必须检查或设置哪个 属性?
Unix 控制台:
$ ./java -cp /usr/test.jar test.mainframe.read.test.TestGetBytes
H = 76 - L
< wasn't found
Windows 控制台:
H = 60 - <
H1 = 69 - E
H2 = 79 - O
H3 = 77 - M
H4 = 62 - >
End of Message found
完整代码:
package test.mainframe.read.test;
import java.util.ArrayList;
public class TestGetBytes {
public static void main(String[] args) {
try {
ArrayList ipmMessage = new ArrayList();
ipmMessage.add(newLine());
//Windows Path
writeMessage("C:/temp/test_bytes.ipm", ipmMessage);
reformatFile("C:/temp/test_bytes.ipm");
//Unix Path
//writeMessage("/usr/temp/test_bytes.ipm", ipmMessage);
//reformatFile("/usr/temp/test_bytes.ipm");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static byte[] newLine() {
return "<EOM>".getBytes();
}
public static void writeMessage(String fileName, ArrayList ipmMessage)
throws java.io.FileNotFoundException, java.io.IOException {
java.io.DataOutputStream dos = new java.io.DataOutputStream(
new java.io.FileOutputStream(fileName, true));
for (int i = 0; i < ipmMessage.size(); i++) {
try {
int[] intValues = (int[]) ipmMessage.get(i);
for (int j = 0; j < intValues.length; j++) {
dos.write(intValues[j]);
}
} catch (ClassCastException e) {
byte[] byteValues = (byte[]) ipmMessage.get(i);
dos.write(byteValues);
}
}
dos.flush();
dos.close();
}
// reformat to U1014
public static void reformatFile(String filename)
throws java.io.FileNotFoundException, java.io.IOException {
java.io.FileInputStream fis = new java.io.FileInputStream(filename);
java.io.DataInputStream br = new java.io.DataInputStream(fis);
int h = br.read();
System.out.println("H = " + h + " - " + (char)h);
if ((char) h == '<') {// Check for <EOM>
int h1 = br.read();
System.out.println("H1 = " + h1 + " - " + (char)h1);
int h2 = br.read();
System.out.println("H2 = " + h2 + " - " + (char)h2);
int h3 = br.read();
System.out.println("H3 = " + h3 + " - " + (char)h3);
int h4 = br.read();
System.out.println("H4 = " + h4 + " - " + (char)h4);
if ((char) h1 == 'E' && (char) h2 == 'O' && (char) h3 == 'M'
&& (char) h4 == '>') {
System.out.println("End of Message found");
}
else{
System.out.println("EOM not found but < was found");
}
}
else{
System.out.println("< wasn't found");
}
}
}
您在调用 getBytes()
时未指定字符集,因此它使用底层平台的默认字符集(如果在 Java 启动时指定,则使用 Java 本身的默认字符集)。这在 String
documentation:
public byte[] getBytes()
Encodes this String into a sequence of bytes using the platform's default charset, storing the result into a new byte array.
getBytes()
有一个重载版本,可让您在代码中指定字符集。
public byte[] getBytes(Charset charset)
Encodes this String into a sequence of bytes using the given charset, storing the result into a new byte array.