Hỏi cách khắc phục lỗi EOFException trong đoạn code

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package File;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 *
 * @author Dell
 */
public class ByteObject {   
    public static void main(String[] args) {                
        
        FileObject.write(new Students(18, "My Hanh", "Thuy Nguyen"));
        FileObject.write(new Students(19, "Van Phuc", "Thuy Nguyen"));
        FileObject.write(new Students(18, "Thai Hoa", "Thuy Nguyen"));
        FileObject.write(new Students(18, "Thai Lan", "Thai Binh"));
        FileObject.write(new Students(18, "Khac An", "Nam Dinh"));
//        
        FileObject.read();                
        
        System.out.println("\n\n\t\tGoodbye!");
    }
}

class FileObject {
    
    private static int confirm = 0;

    public static int getConfirm() {
        return confirm;
    }

    public static void setConfirm(int confirm) {
        FileObject.confirm = confirm;
    }
    
    
    public static void read() {
        
        try {                    
            FileInputStream fi = new FileInputStream("Students.txt");
            ObjectInputStream iStream = new ObjectInputStream(fi);
            
            Students temp;            
            
            while (true) {
                temp = (Students)iStream.readObject();
                System.out.println("" + temp.toString());
            }                     
                       
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    
    public static void write(Object student) {
         
        FileOutputStream fo;
        ObjectOutputStream oStream;
        
        try {                      
           if (getConfirm() == 0) {
               fo = new FileOutputStream("Students.txt");//ghi de. 
               oStream = new ObjectOutputStream(fo);
               setConfirm(1);
           } else {           
               fo = new FileOutputStream("Students.txt", true);//ghi de. 
               oStream = new ObjectOutputStream(fo) {
                    @Override
                    public void writeStreamHeader() throws IOException {                       
                    }
                };
           }
           
           oStream.writeObject(student);
                   
           oStream.close();//phai dong file.
           fo.close();
        } catch (IOException e) {
            e.printStackTrace();                    
        }  
    }
    
}

class Students implements Serializable {
    private int age;
    private String name;
    private String queQuan;

    public Students(int age, String name, String queQuan) {
//        super();
        this.age = age;
        this.name = name;
        this.queQuan = queQuan;
    }

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public String getQueQuan() {
        return queQuan;
    }
    
    @Override
    public String toString() {
        return ("Ban " + getName() + " \tnam nay " + getAge() + " tuoi \t que " + getQueQuan() + "\n");
    }
    
}

Xảy ra trong method readObject. bạn catch ex ở đây là đc

try {
            //
            FileObject.read();
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(ByteObject.class.getName()).log(Level.SEVERE, null, ex);
        }
 public static void read() throws ClassNotFoundException {
        
        try {                    
            FileInputStream fi = new FileInputStream("Students.txt");
            ObjectInputStream iStream = new ObjectInputStream(fi);
            
            Students temp;            
            
            while (iStream.read() <  0) {
                temp = (Students)iStream.readObject();
                System.out.println("" + temp.toString());
            }                     
                       
        }  catch(EOFException eof)
        {
  //end of file reached, do nothing
        }catch(IOException e ){
            
        }
    }

Ừ mình làm như bạn thì cx chạy được rồi, nhưng mình cx tìm hiểu thêm và cái chỗ while (true) {…} thi chỉ cần thay thành while(fi.available() > 0) {…} là được mà không cần phải bắt thêm lỗi EOFException riêng.

Nhưng mà sao bắt lỗi EOFException mà nó vẫn đọc tiếp nhỉ.

1 Like

Bạn có thể tưởng tượng Exception như là lệnh if/else vậy. Esle là 1 dòng lệnh in sự kiện xảy ra.

Để hiểu hơn phải tìm hiểu Checked và Unchecked Exception. Hoặc mở 1 topic khác. Nếu rảnh mình sẽ viết bài nhưng hiện tại thì không

Còn tại sao nó vẫn chạy bạn phải phân biệt đc Exception với Error, Checked khác Unchecked như thế nào.

Error cũng như Uncheck exception vậy được kiểm tra ở thời điểm runtime. Bị đẩy ra bỏi JVM. Là những lỗi mà chương trình không thể sử lý (can not handle) --> Stop

Còn Checked Exception được kiểm tra ở thời điểm complie-time là những lỗi như EOFEXception. Có thể được sử lý được --> chương trình có thể chạy tiếp

Mình có đọc qua Exception va Error, thì biết Error nó cũng là Unchecked Exception nhưng là lỗi thường do hệ thống, nên dù try{}catch(){} thì cũng không ăn thua. Chỉ có Unchecked Exception của RuntimeException extends Exception là bắt lỗi ổn.

Nhưng tại sao nếu nó đã vào khối catch (IOException hay EOFException ) mà vẫn chạy được tiếp vòng lặp để đọc hết file.

Thông thường mình phải để loop structure trong cả khối try catch thì nó mới loop tiếp, thế mà sao cái này lỗi catch rồi mà vẫn loop tiếp được. (Mình cx đã thử qua và thấy nó báo lỗi rồi vẫn đọc tiếp hay do multi Thread? nó hiện lỗi không đúng thứ tự ? liệu có ở đây không.)

Vì nó sử lý đc. Bạn đã đọc cmt của mình chưa vậy?

Chào bạn. Vậy là bạn chưa hiểu rõ bản chất của handle 1 exception rồi. Nếu như bạn không handle exception bằng try catch thì chương trình của bạn sẽ ném ra ngoại lệ và phần còn lại của chương trình sẽ không được chạy. Nếu bạn handle exception bằng try catch thì luồng của chương trình không bị phá vỡ và nó vẫn chạy tiếp, điều này không phải lúc nào cũng đúng vì nó còn tùy thuộc vào loại lỗi nào bạn khai báo trong catch, vì khối try là khối chứa statement có thể xảy ra lỗi, khi gặp lỗi Runtime sẽ ném ra lỗi đó, nếu trong catch khai báo trùng với lỗi đó, thì dòng lệnh sẽ được handle, nếu không khai báo trùng thì Runtime throw 1 exception và chương trình bị phá vỡ. Vậy tùy thuộc vào khối catch bạn bắt lỗi như thế nào nhé.

Cái này không phải vấn đề mình nói đến, cái bạn nói thì mình cx biết rồi, vấn đề mình nói đến là vòng lặp của việc đọc file cơ.

Ví dụ thế này nhé:

try {
while (true) {
int a = 2/0;//loi.
}
} catch (ArithmeticException e) {
//…
}

—> nó sẽ chạy tới int a = 2/0 lỗi nhảy vào catch() và vòng lặp cx không chạy nữa. Và đây chính là câu hỏi của mình. Cũng như ví dụ của bạn DoTrungQuan vậy khi vào EOFException thì đáng ra kết thúc việc đọc (Là đọc file nhé không phải đọc tiếp chương trình , chắc mấy bạn hiểu nhầm ý mình ở đây, sorry viết không rõ)…

Mình vừa phát hiện ra việc đọc file kết thúc mới xảy ra lỗi EOFException nên việc đọc file đã đọc hết nội dung rồi sau đó mới nhảy tới EOFException. Nhầm lẫn cứ nghĩ cái EOFException nó nhảy trong lúc đọc dở file. Mình cảm ơn hai bạn nhé.

Còn đây là cái kết quả lỗi:

run:
Ban My Hanh nam nay 18 tuoi que Thuy Nguyen

Ban Van Phuc 	nam nay 19 tuoi 	 que Thuy Nguyen

Ban Thai Hoa 	nam nay 18 tuoi 	 que Thuy Nguyen

Ban Thai Lan 	nam nay 18 tuoi 	 que Thai Binh

Ban Khac An 	nam nay 18 tuoi 	 que Nam Dinh



		Goodbye!
java.io.EOFException
	at java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2626)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1321)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
	at LuyenDeThi.De7.FileObject.read(ByteObject.java:62)
	at LuyenDeThi.De7.ByteObject.main(ByteObject.java:34)
BUILD SUCCESSFUL (total time: 0 seconds)

Nếu muốn tìm hiểu sâu hơn phải nói đến serialization and deserialization. Đôi khi object bạn cần đọc nó ở cuối file nhưng chưa hết list object bạn cần đọc ra. Nó cũng đẩy ra cái lỗi này. Chứ k phải đọc file kết thúc. Next == null ->> ex

1 Like

Bạn ơi, bạn đặt vòng lặp while bên trong khối try, trong cái khối try đó có câu lệnh ném ra lỗi, tất nhiên vòng lặp While sẽ không được lặp tiếp rồi. Bạn đặt While loop ra bên ngoài và chạy xem nó như thế nào.

Đôi khi object bạn cần đọc nó ở cuối file nhưng chưa hết list object bạn cần đọc ra.

Bạn cho mình ví dụ cụ thể là khi nào được không?

Bạn phải tìm hiểu Serialization trước. Mình không viết bài nhưng mình có reply 1 vấn đề như vậy --> ở đây

Ví dụ bạn muốn lọc các object theo tên và tuổi object có field

object 1 name = "Đỗ Trung Quân" age =25  

nhưng có 2 object nữa như này

object 2 name = "Đỗ Trung Quân" age =26 
object 3 name = "Đỗ Trung Quân" age =27.

Trong khi object lại có nhiều hơn 2 trường. và các trường còn lại mới là yếu tố chính quyết định thứ tự ghi xuống file chứ không phải tên và tuổi.

Thứ tự nó trong file thế này

object 1 name = "Đỗ Trung Quân" age =25
object 3 name = "Đỗ Trung Quân" age =27 
object 2 name = "Đỗ Trung Quân" age =26. //end of file

Nhưng bạn lại muốn đọc theo tuổi hơn kém nhau 1 thôi. Nó sẽ nhảy từ 25 xuống 26 bỏ qua 27, giờ nó muốn quay lại tìm 27 --> EOF

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?