Xin Giúp Lỗi Đọc Dữ Liệu Từ File Txt

banybear2010

New Member
25/10/11
9
0
1
Mình có 2 lớp dữ liệu như sau:
1. Ghi dữ liệu ra file .txt
PHP:
File f=new File(txt_Hinh.getText());
                String path="src/images/images/contact/";
                String duongDan=path+f.getName();
                try
                {
                    Files.copy(f.toPath(),(new File(path + f.getName())).toPath(),StandardCopyOption.REPLACE_EXISTING);
                    System.out.println("Đã đưa hình liên hệ thư mục contact");
                }
                catch (IOException ex) {
                    // TODO: handle exception
                    Logger.getLogger(Bai_9_3.class.getName()).log(Level.SEVERE, null, ex);
                }
                //  lấy dữ liệu gán cho đối tượng liên hệ sau đó ghi vào tập tin lienhe.txt
                String hoTen=txt_HoTen.getText();
                String soDT=txt_SDT.getText();
                String hinhAnh=f.getName();
                LienHe lh=new LienHe(hoTen, soDT, hinhAnh);
                ObjectOutputStream out;
                try {
                    out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("src/baiTap_9_3/lienhe.txt", true))) {
                    @Override
                    protected void writeStreamHeader() throws IOException
                    {
                        reset();
                    }
                    };
                    out.writeObject(lh);
                    out.close();
                    JOptionPane.showMessageDialog(rootPane, "Đã thêm liên hệ: " + lh.getHoTen() + " - " + lh.getDtdd() + " - " + lh.getHinh());
                              } catch (FileNotFoundException ex) {
                            Logger.getLogger(Bai_9_3.class.getName()).log(Level.SEVERE, null, ex);
                              } catch (IOException ex) {
                            Logger.getLogger(Bai_9_3.class.getName()).log(Level.SEVERE, null, ex);
                              }
                              }
        });
------ Lớp 2: Đọc thử dữ liệu thì bị lỗi ----------------
PHP:
private static List<LienHe> lst;
    private static ObjectInputStream in;
    public static void main(String[] args)  {
      
        lst = new ArrayList<>();  
                  
        try {
            in = new ObjectInputStream(new BufferedInputStream(new FileInputStream("src/baiTap_9_3/lienhe.txt")));
            while(true)
            {
                LienHe b = (LienHe) in.readObject();
                lst.add(b);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }  
    for(LienHe ll:lst)
        {
            System.out.println("Ten: "+ll.getHoTen()+" sdt: "+ll.getHinh()+" Hinh: "+ll.getHinh());
        }
    }
**** Cụ thể lỗi như sau:
Code:
java.io.StreamCorruptedException: invalid stream header: 79737200
    at java.i:confused:bjectInputStream.readStreamHeader(Unknown Source)
    at java.i:confused:bjectInputStream.<init>(Unknown Source)
    at baiTap_9_3.DocBai9_.main(DocBai9_.java:20)
Mình ghi thì vẫn ok nó vẫn ghi ra file txt được như khi đọc thì nó lỗi cái phần "stream header" không biết lúc ghi bằng đoạn code trên nó bị vương chỗ nào khi đọc nó không ra được. Xin mọi người giúp dùm ah
 
Last edited by a moderator:

JackV

Administrator
Staff member
Khi bạn sử dụng dòng lệnh
while(true)
{
LienHe b = (LienHe) in.readObject();
lst.add(b);
}
Có thể hiểu là bạn muốn đọc tất cả các lienhe để add vào trong lst, cái vài vấn đề như sau
1. mỗi lần readObject thì stream đọc sẽ di chuyển "đầu đọc" đến đâu và while(true) có nghĩa là làm hoài thì chắc chắn sẽ phải đến lúc nó "ra khỏi rìa" nên sẽ có exception
2. Để đọc được nhiều object thì cách ghi và đọc cũng phải xem lại bạn nhé.
3. Bạn nên làm như sau, tạo ra một list rồi add các lienhe vào sau đó lưu cái list xuống, khi cần đọc dữ liệu thì chỉ cần KieuList lst = (KieuList) in.readObject(); 1 lần là có list để sẵn sàng sử dụng chứ không cần phải while (gì đó) để đọc nhiều lần gây sự phức tạp.
 

banybear2010

New Member
25/10/11
9
0
1
Mình tách nhỏ bài trên test như bạn nói nhưng nó vẫn không đọc được
*Nếu chạy lần 1 thì ok. Chạy tiếp lần 2 thêm vào ds nó chỉ đọc đường dòng đầu trong list, mình nghĩ cơ chế ghi đè vào file cùa mình có vấn đề
java.io.StreamCorruptedException: invalid stream header: 79737200
at java.i:confused:bjectInputStream.readStreamHeader(Unknown Source)
at java.i:confused:bjectInputStream.<init>(Unknown Source)
at baiTap_9_3.GhiDoiTuong.main(GhiDoiTuong.java:61)
-----------------------------------------------------------------------------------
public class GhiDoiTuong implements Serializable {
private static ObjectInputStream in;
private static ObjectOutputStream out;
public static List<GhiDoiTuong> lst=new ArrayList<>();
String ten;
public GhiDoiTuong(String ten, String tuoi) {
super();
this.ten = ten;
this.tuoi = tuoi;
}
public String getTen() {
return ten;
}
public void setTen(String ten) {
this.ten = ten;
}
public String getTuoi() {
return tuoi;
}
public void setTuoi(String tuoi) {
this.tuoi = tuoi;
}
String tuoi;
public static void main(String[] args) throws FileNotFoundException {
GhiDoiTuong dt=new GhiDoiTuong("Hien", "39");
lst.add(dt);
try {
out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("src/thongtin.txt",true))){
out.writeObject(lst);
System.out.println("Ghi Thành Công ");
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// doc doi tuong
FileInputStream fin=new FileInputStream("src/thongtin.txt");
try {
in =new ObjectInputStream(new BufferedInputStream(fin));
lst=(List<GhiDoiTuong>) in.readObject();

for(GhiDoiTuong lh:lst)
{
System.out.println("Tên: "+lh.ten+"\nTuoi: "+lh.tuoi);
}
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
 
Sửa lần cuối:

banybear2010

New Member
25/10/11
9
0
1
You don't understand the working mechanism of ObjectIn/OutputStream and that's the problem you encountered. In Java ObjectStream requires serialized objects which are written:
- randomly: if ObjectStream is closed directly after written then every written object is marked by a header that contains the tag "797372"
- sequentially: if ObjectStream is closed after several written objects then only the first object is marked by a header that contains the tag "797372", the rest (i.e. other followed objects) won't have this tag.

Problem: if you start to read an ObjectStream you have to know HOW the objects were written: randomly or sequentially.
- if the objects were written sequentially your reading LOOP will work.
- if the objects were written randomly your reading LOOP won't work

Reason: If an Object file is opened for WRITE and closed directly thereafter every written then each object is marked by the mentioned header "797372" (random write). NO sequential read is possible (that was your problem with the error message "java.io.StreamCorruptedException: invalid stream header: 79737200").

Solution: to circumsvent the problem object must be read "randomly" as following
PHP:
ObjectInputStream ois = null;
// open the input file
try (FileInputStream in = new FileInputStream("src/thongtin.txt")) {
  while (true) {
    ois = new ObjectInputStream(in) // <<<< reopen each time = random read !!!
    lst.add((GhiDoiTuong) ois.readObject());
  }
} catch (Exception ex) { }
if (ois != null) ois.close();
for(GhiDoiTuong lh:lst) {
   System.out.println("Tên: "+lh.ten+"\nTuoi: "+lh.tuoi);
}
Joe when i change code
while (true) {
ois = new ObjectInputStream(in) // <<<< reopen each time = random read !!!
lst.add((GhiDoiTuong) ois.readObject());
}
It's error here:
ID: 3, Ten: Van Thuan
ID: 6, Ten: Dong Trieu
ID: 3, Ten: Van Thuan
ID: 6, Ten: Dong Trieu
java.io.EOFException
at java.i:confused:bjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.i:confused:bjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.i:confused:bjectInputStream.readStreamHeader(Unknown Source)
at java.i:confused:bjectInputStream.<init>(Unknown Source)
at testObjectInputStream.ObjectInputStreamExample.main(ObjectInputStreamExample.java:26)
 

Joe

Thành viên VIP
21/1/13
2,885
1,288
113
It's error here:
...
java.io.EOFException
....
EOF = End Of File....That's the reason while the LOOP must be withing the try-catch
PHP:
try (FileInputStream in = new FileInputStream("src/thongtin.txt")) {
  while (true) {
    ois = new ObjectInputStream(in) // <<<< reopen each time = random read !!!
    lst.add((GhiDoiTuong) ois.readObject()); 
  }
} catch (Exception ex) { } // Ignore EOF here
 
  • Like
Reactions: banybear2010