Java InputStream.readAllBytes() returns 比写的多
Java InputStream.readAllBytes() returns more than what was written
我有这个代码
public static void main(String[] args) throws Exception {
try (PythonInterpreter pi = new PythonInterpreter()) {
String sourceString = "print 'compiled!'";
String name = "mymodule";
// Dress the String as bytes: compiler not v good with encodings.
InputStream source = new InputStream() {
ByteBuffer buf = StandardCharsets.US_ASCII.encode(sourceString);
@Override
public int read() throws IOException {
if (buf.remaining() > 0) {
return buf.get() & 0xff;
} else {
return -1;
}
}
};
byte[] javaCode = imp.compileSource(name, source, "<string>");
String className = name + "$py";
System.out.println(String.format("Original length: %s", javaCode.length));
PyCode code = BytecodeLoader.makeCode(className, javaCode, "<string>");
System.out.println(String.format("Code: %s", code));
pi.exec(code);
// You can write a file and read it back if you want :)
byte[] javaCode2 = javaCode.clone();
System.out.println(String.format("Read in length: %s", javaCode2.length));
if (javaCode2.length == javaCode.length){
System.out.println(String.format("Are equal: %s", Arrays.equals(javaCode, javaCode2)));
}
PyCode code2 = BytecodeLoader.makeCode(className, javaCode2, "<file>");
System.out.println(String.format("Code: %s", code2));
pi.exec(code2);
} catch (Exception e) {
e.printStackTrace();
}
}
输出
Original length: 2125
Code: <code object <module> at 0x2, file "<string>", line 0>
compiled!
Read in length: 2125
Are equal: true
Code: <code object <module> at 0x3, file "<file>", line 0>
compiled!
一切都很好,但是,当我将单行 javaCode.clone()
交换为写入然后从文件读取时
public static void main(String[] args) throws Exception {
try (PythonInterpreter pi = new PythonInterpreter()) {
String sourceString = "print 'compiled!'";
String name = "mymodule";
// Dress the String as bytes: compiler not v good with encodings.
InputStream source = new InputStream() {
ByteBuffer buf = StandardCharsets.US_ASCII.encode(sourceString);
@Override
public int read() throws IOException {
if (buf.remaining() > 0) {
return buf.get() & 0xff;
} else {
return -1;
}
}
};
byte[] javaCode = imp.compileSource(name, source, "<string>");
String className = name + "$py";
System.out.println(String.format("Original length: %s", javaCode.length));
PyCode code = BytecodeLoader.makeCode(className, javaCode, "<string>");
System.out.println(String.format("Code: %s", code));
pi.exec(code);
/// CHANGE STARTS HERE
OutputStream os =
Files.newOutputStream(Paths.get("compiled_code"), StandardOpenOption.CREATE);
System.out.println(String.format("os: %s", os));
os.write(javaCode);
os.close();
InputStream is =
Files.newInputStream(Paths.get("compiled_code"), StandardOpenOption.READ);
System.out.println(String.format("is: %s", is));
byte[] javaCode2 = is.readAllBytes();
is.close();
/// CHANGE ENDS HERE
System.out.println(String.format("Read in length: %s", javaCode2.length));
if (javaCode2.length == javaCode.length){
System.out.println(String.format("Are equal: %s", Arrays.equals(javaCode, javaCode2)));
}
PyCode code2 = BytecodeLoader.makeCode(className, javaCode2, "<file>");
System.out.println(String.format("Code: %s", code2));
pi.exec(code2);
} catch (Exception e) {
e.printStackTrace();
}
}
输出变为
Original length: 2125
Code: <code object <module> at 0x2, file "<string>", line 0>
compiled!
os: java.nio.channels.Channels@3533df16
is: sun.nio.ch.ChannelInputStream@14ac77b9
Read in length: 2152
Exception in thread "main" java.lang.ClassFormatError: Extra bytes at the end of class file mymodule$py
我的问题是,为什么 readAllBytes()
给出了一个长度为 2152 的字节数组(比给 os.write()
的多了 27 个字节)?
我检查了一下,javaCode2中的所有字节都是正确的,只要你忽略多余的27就可以了。
额外的是
0 88 0 1 0 89 73 0 90 0 91 0 1 0 89 74 0 92 0 94 0 1 0 89 115 0 95
您可能正在覆盖现有文件,更改为使用截断以及将文件大小重置为零:
Path path = Paths.get("compiled_code");
OutputStream os = Files.newOutputStream(path, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
但是,使用 Files
的内置调用进行 byte[]
读取和写入会更好 - 节省几行代码,并且可以省略 try-with-resources 流处理或 close()
操作:
Files.write(path, javaCode);
和
byte[] javaCode2 = Files.readAllBytes(path);
我有这个代码
public static void main(String[] args) throws Exception {
try (PythonInterpreter pi = new PythonInterpreter()) {
String sourceString = "print 'compiled!'";
String name = "mymodule";
// Dress the String as bytes: compiler not v good with encodings.
InputStream source = new InputStream() {
ByteBuffer buf = StandardCharsets.US_ASCII.encode(sourceString);
@Override
public int read() throws IOException {
if (buf.remaining() > 0) {
return buf.get() & 0xff;
} else {
return -1;
}
}
};
byte[] javaCode = imp.compileSource(name, source, "<string>");
String className = name + "$py";
System.out.println(String.format("Original length: %s", javaCode.length));
PyCode code = BytecodeLoader.makeCode(className, javaCode, "<string>");
System.out.println(String.format("Code: %s", code));
pi.exec(code);
// You can write a file and read it back if you want :)
byte[] javaCode2 = javaCode.clone();
System.out.println(String.format("Read in length: %s", javaCode2.length));
if (javaCode2.length == javaCode.length){
System.out.println(String.format("Are equal: %s", Arrays.equals(javaCode, javaCode2)));
}
PyCode code2 = BytecodeLoader.makeCode(className, javaCode2, "<file>");
System.out.println(String.format("Code: %s", code2));
pi.exec(code2);
} catch (Exception e) {
e.printStackTrace();
}
}
输出
Original length: 2125
Code: <code object <module> at 0x2, file "<string>", line 0>
compiled!
Read in length: 2125
Are equal: true
Code: <code object <module> at 0x3, file "<file>", line 0>
compiled!
一切都很好,但是,当我将单行 javaCode.clone()
交换为写入然后从文件读取时
public static void main(String[] args) throws Exception {
try (PythonInterpreter pi = new PythonInterpreter()) {
String sourceString = "print 'compiled!'";
String name = "mymodule";
// Dress the String as bytes: compiler not v good with encodings.
InputStream source = new InputStream() {
ByteBuffer buf = StandardCharsets.US_ASCII.encode(sourceString);
@Override
public int read() throws IOException {
if (buf.remaining() > 0) {
return buf.get() & 0xff;
} else {
return -1;
}
}
};
byte[] javaCode = imp.compileSource(name, source, "<string>");
String className = name + "$py";
System.out.println(String.format("Original length: %s", javaCode.length));
PyCode code = BytecodeLoader.makeCode(className, javaCode, "<string>");
System.out.println(String.format("Code: %s", code));
pi.exec(code);
/// CHANGE STARTS HERE
OutputStream os =
Files.newOutputStream(Paths.get("compiled_code"), StandardOpenOption.CREATE);
System.out.println(String.format("os: %s", os));
os.write(javaCode);
os.close();
InputStream is =
Files.newInputStream(Paths.get("compiled_code"), StandardOpenOption.READ);
System.out.println(String.format("is: %s", is));
byte[] javaCode2 = is.readAllBytes();
is.close();
/// CHANGE ENDS HERE
System.out.println(String.format("Read in length: %s", javaCode2.length));
if (javaCode2.length == javaCode.length){
System.out.println(String.format("Are equal: %s", Arrays.equals(javaCode, javaCode2)));
}
PyCode code2 = BytecodeLoader.makeCode(className, javaCode2, "<file>");
System.out.println(String.format("Code: %s", code2));
pi.exec(code2);
} catch (Exception e) {
e.printStackTrace();
}
}
输出变为
Original length: 2125
Code: <code object <module> at 0x2, file "<string>", line 0>
compiled!
os: java.nio.channels.Channels@3533df16
is: sun.nio.ch.ChannelInputStream@14ac77b9
Read in length: 2152
Exception in thread "main" java.lang.ClassFormatError: Extra bytes at the end of class file mymodule$py
我的问题是,为什么 readAllBytes()
给出了一个长度为 2152 的字节数组(比给 os.write()
的多了 27 个字节)?
我检查了一下,javaCode2中的所有字节都是正确的,只要你忽略多余的27就可以了。
额外的是
0 88 0 1 0 89 73 0 90 0 91 0 1 0 89 74 0 92 0 94 0 1 0 89 115 0 95
您可能正在覆盖现有文件,更改为使用截断以及将文件大小重置为零:
Path path = Paths.get("compiled_code");
OutputStream os = Files.newOutputStream(path, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
但是,使用 Files
的内置调用进行 byte[]
读取和写入会更好 - 节省几行代码,并且可以省略 try-with-resources 流处理或 close()
操作:
Files.write(path, javaCode);
和
byte[] javaCode2 = Files.readAllBytes(path);