ObjectInputStream 在使用 ByteArrayInputStream 构造后没有可用字节
ObjectInputStream doesn't have available bytes after being constructed with a ByteArrayInputStream
我正在构建一个处理二进制 De/Serialization 的 class。方法 open()
接收一个 InputStream
和一个 OutputStream
。这些是由另一个接收路径作为参数的 open()
方法创建的。 InputStream
实际上是 ByteArrayInputStream
。
我已经做了一些测试来证明 InputStream
正在到达带有内容的 open()
方法 - 它确实是。但是当我尝试使用它设置 ObjectInputStream
时,它不起作用。没有抛出异常,但是当我尝试从中读取字节时,它总是给我 -1
.
BinaryStrategy class
public class BinaryStrategy implements SerializableStrategy{
public BinaryStrategy(){
try{
open("products.ser");
}catch(IOException ioe){
}
}
@Override
public void open(InputStream input, OutputStream output) throws IOException {
try{
this.ois = new ObjectInputStream(input);
}catch(Exception ioe){
System.out.println(ioe);
}
this.oos = new ObjectOutputStream(output);
}
@Override
public void writeObject(fpt.com.Product obj) throws IOException {
oos.writeObject(obj);
oos.flush();
}
@Override
public Product readObject() throws IOException {
Product read = new Product();
try{
read.readExternal(ois);
}catch(IOException | ClassNotFoundException exc){
System.out.println(exc);
}
return read;
}
}
interface SerializableStrategy (just the default method)
default void open(Path path) throws IOException {
if (path != null) {
ByteArrayInputStream in = null;
if (Files.exists(path)) {
byte[] data = Files.readAllBytes(path);
in = new ByteArrayInputStream(data);
}
OutputStream out = Files.newOutputStream(path);
open(in, out);
}
Product class
public class Product implements java.io.Externalizable {
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeLong(getId());
out.writeObject(getName());
out.writeObject(getPrice());
out.writeObject(getQuantity());
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.setId((Long)in.readLong());
this.setName((String) in.readObject());
this.setPrice((Double) in.readObject());
this.setQuantity((Integer) in.readObject());
}
我必须对其进行个性化设置,因为属性是 SimpleProperty
s
在 public void open(InputStream input, OutputStream output)
我尝试做一些如下测试:
public void open(InputStream input, OutputStream output) throws IOException {
try{
System.out.println(input.available() + " " + input.read() + " " + input.read());
//is gives me: 181 172 237
//181 is the exact size of the file I have, so i think that the Output is ok
//172 237 - just some chars that are in the file
//I know that for now on it is going to give me an excepetion because
// of the position of the index that is reading. I did it just to test
this.ois = new ObjectInputStream(input);
}catch(Exception ioe){
System.out.println(ioe);
}
this.oos = new ObjectOutputStream(output);
}
然后是其他测试:
public void open(InputStream input, OutputStream output) throws IOException {
try{
this.ois = new ObjectInputStream(input);
System.out.println(ois.available() + " " + ois.read());
//here is where I am receiving -1 and 0 available bytes!
//so something is going wrong right here.
//i tried to just go on and try to read the object,
//but I got a EOFException, in other words, -1.
}catch(Exception ioe){
System.out.println(ioe);
}
this.oos = new ObjectOutputStream(output);
}
请检查 path
代表的文件是否写入了 java 对象。
来自 ObjectInputStream API 文档 https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html
An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream.
ObjectInputStream is used to recover those objects previously serialized.
如果您正在执行 this.ois.readObject()
,并且您正在执行 -1
,则文件中可能不包含对象。
更新:readObject
returns 一个对象而不是 int
。如果您在 ois
中使用 read
方法,并且得到 -1
,则文件为空。
此外,您的文件有可能包含 -1 作为其内容 ;)
问题是我读 ObjectInputStream
的方式不对。就像:
read.readExternal(ois);
但正确的方法是:
read = (Product)ois.readObject();
并且由于我这样做时遇到的异常,我认为问题出在使用 ByteArrayInputStream
时 ObjectInputStream
的构造上。
多么大的错误! :D
感谢所有试图提供帮助的人。
ObjectInputStream
,内部使用一个BlockDataInputStream
执行它的读操作。当您调用 read
时,这会读取一个数据块,而不仅仅是我们预期的一个字节。只有当它落在 "block"
时它才读取一个字节
输出也不是我所期望的。
但是,如果您查看 ObjectInputStream.read()
的代码,它是有道理的。
因此,在您的情况下,仅使用 readObject
来恢复对象的状态是有意义的。
又是你的代码...
class SimpleJava {
public static void open(InputStream input, OutputStream output) throws IOException {
try {
ObjectInputStream ois = new ObjectInputStream(input);
System.out.println(ois.available());// 0
System.out.println(ois.available() + " " + ois.read() + " " + ois.read());// 0 -1 -1
// Reads the object even if the available returned 0
// and ois.read() returned -1
System.out.println("object:" + ois.readObject());// object:abcd
}
catch (Exception ioe) {
ioe.printStackTrace();
}
}
static void open(Path path) throws IOException {
if (path != null) {
ByteArrayInputStream in = null;
if (Files.exists(path)) {
byte[] data = Files.readAllBytes(path);
in = new ByteArrayInputStream(data);
}
OutputStream out = Files.newOutputStream(path);
open(in, out);
}
}
public static void main(String[] args) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("/home/pradhan/temp.object")));
oos.writeObject("abcd");//writes a string object for us to read later
oos.close();
//
open(FileSystems.getDefault().getPath("/home/user/temp.object"));
}
}
这是输出...
0
0 -1 -1
object:abcd
我正在构建一个处理二进制 De/Serialization 的 class。方法 open()
接收一个 InputStream
和一个 OutputStream
。这些是由另一个接收路径作为参数的 open()
方法创建的。 InputStream
实际上是 ByteArrayInputStream
。
我已经做了一些测试来证明 InputStream
正在到达带有内容的 open()
方法 - 它确实是。但是当我尝试使用它设置 ObjectInputStream
时,它不起作用。没有抛出异常,但是当我尝试从中读取字节时,它总是给我 -1
.
BinaryStrategy class
public class BinaryStrategy implements SerializableStrategy{
public BinaryStrategy(){
try{
open("products.ser");
}catch(IOException ioe){
}
}
@Override
public void open(InputStream input, OutputStream output) throws IOException {
try{
this.ois = new ObjectInputStream(input);
}catch(Exception ioe){
System.out.println(ioe);
}
this.oos = new ObjectOutputStream(output);
}
@Override
public void writeObject(fpt.com.Product obj) throws IOException {
oos.writeObject(obj);
oos.flush();
}
@Override
public Product readObject() throws IOException {
Product read = new Product();
try{
read.readExternal(ois);
}catch(IOException | ClassNotFoundException exc){
System.out.println(exc);
}
return read;
}
}
interface SerializableStrategy (just the default method)
default void open(Path path) throws IOException {
if (path != null) {
ByteArrayInputStream in = null;
if (Files.exists(path)) {
byte[] data = Files.readAllBytes(path);
in = new ByteArrayInputStream(data);
}
OutputStream out = Files.newOutputStream(path);
open(in, out);
}
Product class
public class Product implements java.io.Externalizable {
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeLong(getId());
out.writeObject(getName());
out.writeObject(getPrice());
out.writeObject(getQuantity());
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.setId((Long)in.readLong());
this.setName((String) in.readObject());
this.setPrice((Double) in.readObject());
this.setQuantity((Integer) in.readObject());
}
我必须对其进行个性化设置,因为属性是 SimpleProperty
s
在 public void open(InputStream input, OutputStream output)
我尝试做一些如下测试:
public void open(InputStream input, OutputStream output) throws IOException {
try{
System.out.println(input.available() + " " + input.read() + " " + input.read());
//is gives me: 181 172 237
//181 is the exact size of the file I have, so i think that the Output is ok
//172 237 - just some chars that are in the file
//I know that for now on it is going to give me an excepetion because
// of the position of the index that is reading. I did it just to test
this.ois = new ObjectInputStream(input);
}catch(Exception ioe){
System.out.println(ioe);
}
this.oos = new ObjectOutputStream(output);
}
然后是其他测试:
public void open(InputStream input, OutputStream output) throws IOException {
try{
this.ois = new ObjectInputStream(input);
System.out.println(ois.available() + " " + ois.read());
//here is where I am receiving -1 and 0 available bytes!
//so something is going wrong right here.
//i tried to just go on and try to read the object,
//but I got a EOFException, in other words, -1.
}catch(Exception ioe){
System.out.println(ioe);
}
this.oos = new ObjectOutputStream(output);
}
请检查 path
代表的文件是否写入了 java 对象。
来自 ObjectInputStream API 文档 https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html
An ObjectInputStream deserializes primitive data and objects previously written using an ObjectOutputStream.
ObjectInputStream is used to recover those objects previously serialized.
如果您正在执行 this.ois.readObject()
,并且您正在执行 -1
,则文件中可能不包含对象。
更新:readObject
returns 一个对象而不是 int
。如果您在 ois
中使用 read
方法,并且得到 -1
,则文件为空。
此外,您的文件有可能包含 -1 作为其内容 ;)
问题是我读 ObjectInputStream
的方式不对。就像:
read.readExternal(ois);
但正确的方法是:
read = (Product)ois.readObject();
并且由于我这样做时遇到的异常,我认为问题出在使用 ByteArrayInputStream
时 ObjectInputStream
的构造上。
多么大的错误! :D
感谢所有试图提供帮助的人。
ObjectInputStream
,内部使用一个BlockDataInputStream
执行它的读操作。当您调用 read
时,这会读取一个数据块,而不仅仅是我们预期的一个字节。只有当它落在 "block"
输出也不是我所期望的。
但是,如果您查看 ObjectInputStream.read()
的代码,它是有道理的。
因此,在您的情况下,仅使用 readObject
来恢复对象的状态是有意义的。
又是你的代码...
class SimpleJava {
public static void open(InputStream input, OutputStream output) throws IOException {
try {
ObjectInputStream ois = new ObjectInputStream(input);
System.out.println(ois.available());// 0
System.out.println(ois.available() + " " + ois.read() + " " + ois.read());// 0 -1 -1
// Reads the object even if the available returned 0
// and ois.read() returned -1
System.out.println("object:" + ois.readObject());// object:abcd
}
catch (Exception ioe) {
ioe.printStackTrace();
}
}
static void open(Path path) throws IOException {
if (path != null) {
ByteArrayInputStream in = null;
if (Files.exists(path)) {
byte[] data = Files.readAllBytes(path);
in = new ByteArrayInputStream(data);
}
OutputStream out = Files.newOutputStream(path);
open(in, out);
}
}
public static void main(String[] args) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("/home/pradhan/temp.object")));
oos.writeObject("abcd");//writes a string object for us to read later
oos.close();
//
open(FileSystems.getDefault().getPath("/home/user/temp.object"));
}
}
这是输出...
0
0 -1 -1
object:abcd