package Wardrobe;import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Scanner;
源代码:package Wardrobe;import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Scanner;
public class Test {

public static void main(String args[]) throws IOException, ClassNotFoundException, EOFException{
/**
 * Data initialization
 */
ArrayList<FamilyMember> userData=new ArrayList<FamilyMember>();
StorageLocation bedroom=new StorageLocation("BedRoom",1);//initialize the default storageLocation
Wardrobe w1=new Wardrobe(bedroom,1);//initialize the wardrobe
FamilyMember father=new FamilyMember("Jack",1000,1000);
FamilyMember mother=new FamilyMember("Rose",1001,1001);
FamilyMember son=new FamilyMember("Billy",1002,1002);//three default familyMembers
userData.add(mother);
userData.add(father);
userData.add(son);//add default familyMembers to arrayList
Item i1=new Item("Nike","Black",500,2013,175,father,"Cloth","Nice");
Item i2=new Item("Adidas","White",300,2012,75,mother,"Bag","Too big");//two default items
w1.addItem(i1);
w1.addItem(i2);//add default items to wardrobe

/**
 * login window
 */
System.out.println("===============================");
System.out.println("|       Wardrobe System       |");
System.out.println("===============================");
Scanner scanner=new Scanner(System.in);
int tempID=0,tempPassword=0;
boolean userCheckState=false;
System.out.printf("Please Input The UserID:");
tempID=scanner.nextInt();
System.out.printf("Please Input The Password:");
tempPassword=scanner.nextInt();//scan the ID number and password the user types in
for(FamilyMember i:userData){//check if it suits one of FamilyMember
if(i.getID()==tempID&&i.getPassword()==tempPassword){
System.out.println("Successfully login!");
userCheckState=true;
break;
}
}
if(!userCheckState){
System.out.println("Wrong ID or Password!");
}
FileInputStream fi=new FileInputStream("file");
ObjectInputStream oi=new ObjectInputStream(fi); ArrayList<Wardrobe> SL=new ArrayList<Wardrobe>();
while(oi.readObject()!=null){
SL.add((Wardrobe)oi.readObject());//就是这行代码出错。。
}
/**
 * function view for users to
 * find the command which they
 * want to operate
 */
System.out.println("================================");
System.out.println("|Function View:                |");
System.out.println("|==============================|");
System.out.println("|1.view  :|show all the item   |");
System.out.println("|==============================|");
System.out.println("|2.add   :|add a item          |");
System.out.println("|==============================|");
System.out.println("|3.remove:|remove a item       |");
System.out.println("|==============================|");
System.out.println("|4.cal   :|calculate the costs |");
System.out.println("|==============================|");
System.out.println("|5.exit  :|exit the application|");
System.out.println("|==============================|");

/**
 * main program for user
 * to do some operations 
 * on wardrobe
 */
while(true){
System.out.print("Please Input The Command:");
String command=scanner.nextLine();
switch (command){
case "view":
w1.show();break;
case "add":
Item tempItem=new Item();
String temp=null;
System.out.print("Please Input The Name:");
tempItem.setName(scanner.nextLine());
System.out.print("Please Input The Color:");
tempItem.setColor(scanner.nextLine());
System.out.print("Please Input The price:");
tempItem.setPrice(scanner.nextInt());
System.out.print("Please Input The purchasedate:");
tempItem.setPurchasedate(scanner.nextInt());
System.out.print("Please Input The Size:");
tempItem.setSize(scanner.nextFloat());
System.out.print("Please Input The ownner:");
temp=scanner.nextLine();
for(FamilyMember i:userData){
if(i.getName()==temp){
tempItem.setOwner(i);
break;
}
}
System.out.print("Please Input The Type:");
tempItem.setType(scanner.nextLine());
System.out.print("Please Input The Comment:");
tempItem.setComment(scanner.nextLine());
w1.addItem(tempItem);
break;
case "search":
System.out.print("Please Input The Key Word:");
w1.search(scanner.nextLine());
case "remove":
System.out.print("Please Input The Number:");
w1.removeItem(scanner.nextInt());
break;
case "cal":
System.out.println("All costs:"+w1.calculatecost());
break;
case "exit":
System.exit(0);
default:
System.out.println("Wrong Input!");
break;
} FileOutputStream fo=new FileOutputStream("file");
ObjectOutputStream oo=new ObjectOutputStream(fo);
oo.writeObject(i2);

}

}}
出现的错误是:
Exception in thread "main" java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2596)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1316)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
at Wardrobe.Test.main(Test.java:66网上找了好久的答案没有找到解决方法
错误的意思是读取文件到达文件末尾却还在继续读取所以发生错误
我尝试过先写一边再去读,失败
只有在读之前先写才不会报错
但是我想要实现程序关闭之后数据依然存在,并且可以在程序下次执行时被读取的功能
求助各位高手帮小弟解决一下,不胜感激。

解决方案 »

  1.   

    while(oi.readObject()!=null){
                SL.add((Wardrobe)oi.readObject());//就是这行代码出错。。
            }修改为
    Object obj = null;
    while((obj=oi.readObject())!=null){
                SL.add((Wardrobe)obj);//就是这行代码出错。。
            }试试
      

  2.   

    建议使用try catch finally的方式,替代throws另外,file文件是否在当前目录下存在,并且是通过ObjectOutputStream 实现的Wardrobe类对象的序列化内容?
      

  3.   

    我用的Eclipse,所以不在同一个目录下面,我的代码在src里面,file自动生成在src外面
    Wardrobe类对象实现了序列化接口的另外我用了try和catch,并且把我的代码改成rumlee大哥说得那样于是出现了另外一个错误
    Exception in thread "main" java.lang.ClassCastException: Wardrobe.Item cannot be cast to Wardrobe.Wardrobe
    at Wardrobe.Test.main(Test.java:70)
    修改的代码如下
    try{
    FileInputStream fi=new FileInputStream("file");
    ObjectInputStream oi=new ObjectInputStream(fi); ArrayList<Wardrobe> SL=new ArrayList<Wardrobe>();
    Object obj = null;
    while((obj=oi.readObject())!=null){
    SL.add((Wardrobe)obj);
             }
    }
    catch (EOFException e) {
    e.printStackTrace();
    }
      

  4.   

    首先你需要确认你的序列化对象文件内容对不对,你那个file文件是不是使用ObjectOutputStream 写入的。不然你使用ObjectInputStream读取的时候自然会报错。其次,序列化对象内部持有的对象也必须继承序列化接口。
      

  5.   

    如果实在不需要序列化,属性使用transient修饰。
      

  6.   

    我用的Eclipse,所以不在同一个目录下面,我的代码在src里面,file自动生成在src外面
    Wardrobe类对象实现了序列化接口的另外我用了try和catch,并且把我的代码改成rumlee大哥说得那样于是出现了另外一个错误
    Exception in thread "main" java.lang.ClassCastException: Wardrobe.Item cannot be cast to Wardrobe.Wardrobe
    at Wardrobe.Test.main(Test.java:70)
    修改的代码如下
    try{
    FileInputStream fi=new FileInputStream("file");
    ObjectInputStream oi=new ObjectInputStream(fi); ArrayList<Wardrobe> SL=new ArrayList<Wardrobe>();
    Object obj = null;
    while((obj=oi.readObject())!=null){
    SL.add((Wardrobe)obj);
             }
    }
    catch (EOFException e) {
    e.printStackTrace();
    }
    你这是强制类型转换错误,说明文件读出来的不是Wardrobe类型啊。
    你可以输出一下obj的类型是什么啊。
    如果确定是Wardrobe类型,则确认一下Wardrobe类有没有定义serialVersionUID属性。
      

  7.   

    我用的Eclipse,所以不在同一个目录下面,我的代码在src里面,file自动生成在src外面
    Wardrobe类对象实现了序列化接口的另外我用了try和catch,并且把我的代码改成rumlee大哥说得那样于是出现了另外一个错误
    Exception in thread "main" java.lang.ClassCastException: Wardrobe.Item cannot be cast to Wardrobe.Wardrobe
    at Wardrobe.Test.main(Test.java:70)
    修改的代码如下
    try{
    FileInputStream fi=new FileInputStream("file");
    ObjectInputStream oi=new ObjectInputStream(fi); ArrayList<Wardrobe> SL=new ArrayList<Wardrobe>();
    Object obj = null;
    while((obj=oi.readObject())!=null){
    SL.add((Wardrobe)obj);
             }
    }
    catch (EOFException e) {
    e.printStackTrace();
    }
    你这是强制类型转换错误,说明文件读出来的不是Wardrobe类型啊。
    你可以输出一下obj的类型是什么啊。
    如果确定是Wardrobe类型,则确认一下Wardrobe类有没有定义serialVersionUID属性。恩,有道理,那个错误应该是这个原因才对。
    readObject方法会从序列化二进制文件头部到尾部依次找Object类型的数据,那个内部属性Item也是对象而且也被写入到了序列化二进制文件里,所以这个循环也会读到Item对象。
    建议循环内加上 instanceOf Wardrobe 判断,满足条件再强转。
      

  8.   

    你先fileInputStream.使用fi.read();看看有没有内容。别fi。本身就是个空的输入流
      

  9.   

    我用的Eclipse,所以不在同一个目录下面,我的代码在src里面,file自动生成在src外面
    Wardrobe类对象实现了序列化接口的另外我用了try和catch,并且把我的代码改成rumlee大哥说得那样于是出现了另外一个错误
    Exception in thread "main" java.lang.ClassCastException: Wardrobe.Item cannot be cast to Wardrobe.Wardrobe
    at Wardrobe.Test.main(Test.java:70)
    修改的代码如下
    try{
    FileInputStream fi=new FileInputStream("file");
    ObjectInputStream oi=new ObjectInputStream(fi); ArrayList<Wardrobe> SL=new ArrayList<Wardrobe>();
    Object obj = null;
    while((obj=oi.readObject())!=null){
    SL.add((Wardrobe)obj);
             }
    }
    catch (EOFException e) {
    e.printStackTrace();
    }
    你这是强制类型转换错误,说明文件读出来的不是Wardrobe类型啊。
    你可以输出一下obj的类型是什么啊。
    如果确定是Wardrobe类型,则确认一下Wardrobe类有没有定义serialVersionUID属性。恩,有道理,那个错误应该是这个原因才对。
    readObject方法会从序列化二进制文件头部到尾部依次找Object类型的数据,那个内部属性Item也是对象而且也被写入到了序列化二进制文件里,所以这个循环也会读到Item对象。
    建议循环内加上 instanceOf Wardrobe 判断,满足条件再强转。
    谢谢各位的答复
    我最后用了三个catch问题解决了。。具体我也不是很清楚为什么
    代码如下
    try {
    FileInputStream fi=new FileInputStream("file");
    ObjectInputStream oi=new ObjectInputStream(fi); Object obj = null;
    obj=oi.readObject();
    SL=(ArrayList<Wardrobe>)obj;
            
    } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    另外我还有一个问题
    就是比如我要序列化一个对象叫做A
    然后A里面有另外一个List比如是ArrayList<B>
    然后这个List里面比如有两个对象b1=new B(),b2=new B(),
    那么我序列化之后这个List的信息会一起得以保存到文件中么?因为我现在遇到一个问题
    就是我从文件当中读取A是可行的,但是A当中的List却没有了
    变成了一个空的List,也就是说b1和b2丢失了另外求程序数据存储到文件当中的理想的解决方案
    就是运行程序之后对数据修改了我希望下次打开数据还是上次关闭之前的状态
    应该用什么方法实现比较妥当,在此再次谢谢各位的答复!
      

  10.   

    不会啊,只要list中的元素也是可以序列化的就行。
    例子,下面 Persion中含有一个List,就可以反序列化。import java.io.*;
    import java.util.*;class Teacher implements Serializable
    {
    String name = "";
    Teacher(String name)
    {
    this.name = name;
    } public String toString()
    {
    return "["+name+"]";
    }
    }
    class Persion implements Serializable
    {
    List<Teacher> names = new ArrayList<Teacher>();
    String name;
    Persion(String name)
    {
    this.name = name;
    names.add(new Teacher("唐僧"));
    names.add(new Teacher("菩提老祖"));
    }
    }public class SerialTest  
    {

    public static void main(String[] args) 
    {
    //序列化

    try
    ( ObjectOutputStream oos = new ObjectOutputStream(
    new FileOutputStream("obj.txt"));)
    {
    Persion per = new Persion("孙悟空");
    oos.writeObject(per);
    }
    catch (Exception e)
    {
    e.printStackTrace();
    }
    //反列化
    try
    (ObjectInputStream ois = new ObjectInputStream(
    new FileInputStream("obj.txt"));)
    {
    Persion p = (Persion)ois.readObject();
    System.out.println(p.name);
    for (Teacher t:p.names )
    {
    System.out.println(t);
    }
    }
    catch (Exception e)
    {
    e.printStackTrace();
    } System.out.println("Hello World!");
    }
    }
      

  11.   

    看ObjectInputstream 的API:
    ObjectInputStream 对以前使用 ObjectOutputStream 写入
    的基本数据和对象进行反序列化。readObject 方法用于从流读取对象。
    应该使用 Java 的安全强制转换来获取所需的类型。
    在 Java 中,字符串和数组都是对象,所以在序列化期间将其视为对象。
    读取时,需要将其强制转换为期望的类型。 
    楼主刚开始的时候应该是转换问题
      

  12.   

    谢谢你的答复。问题现在解决了。。说的没错。只要list也是能序列化的就行谢谢你的答复。。现在对这个已经熟悉很多了
    实践果然出真理