2015-12-25 15 views
6

Tôi đang gặp một số sự cố với hai phương pháp mà tôi đã cố gắng viết. Cả hai đều liên quan đến việc sử dụng một Máy quét để đọc trong một tệp, trong đó mỗi dòng được phân tách bằng dấu phẩy. Các phương thức này là một phần của lớp FileIO của tôi. Ngoài lớp học đó, tôi còn có hai lớp khác, Food và FoodArrayList. Các đối tượng thực phẩm có chứa một số thông tin từ các khoản quyên góp thực phẩm (những người quyên góp các mặt hàng, lý do quyên góp, vv). Lớp FoodArrayList khá nhiều có chức năng giống như một ArrayList, ngoại trừ việc tôi đã tạo ra nó chỉ với mục đích lưu trữ các đối tượng Thực phẩm.Cách kiểm tra xem máy quét có bị đóng

Hai phương pháp Tôi đang phải vật lộn với như sau:

  1. Đọc trong file và chỉ cần đếm số dòng trong file. Nó trả về số dòng. Phương pháp này được sử dụng để xác định kích thước của một FoodArrayList. Điều này là do mỗi dòng của tệp mô tả đối tượng Thực phẩm.
  2. Đọc trong tệp và lưu trữ thông tin vào đối tượng FoodArrayList. Hãy nhớ rằng mỗi dòng phân cách bằng dấu phẩy mô tả đối tượng Thực phẩm. Do đó, phương pháp này đi qua các tập tin, tạo ra các đối tượng thực phẩm, và chèn chúng vào một FoodArrayList cho đến khi nó đạt đến cuối của tập tin.

Điều tôi đang gặp phải là tôi đóng Máy quét của mình theo cả hai phương pháp. Và tôi đã đấu tranh với cách viết một câu lệnh if để phát hiện xem Máy quét đã được đóng chưa. Trong cả hai phương pháp, tôi có những điều sau đây ngay từ đầu phương thức:

try{ 
     if(scan.hasNext() == false || scan == null) 
      scan = new Scanner(new File(this.getFileName())); 
    } 
    catch(FileNotFoundException fnfe){ 
     System.err.println("The " + fileName + " could not be found."); 
    } 
    catch(IOException ioe){ 
     ioe.printStackTrace(); 
    } 

Điều này dường như không hoạt động. Nếu tôi sử dụng phương pháp # 1 đầu tiên và sau đó thử sử dụng phương pháp # 2 (nhớ rằng tôi đóng Máy quét ở cuối mỗi phương pháp), câu lệnh if bị bỏ qua và scan không bao giờ được khôi phục và tôi bị ném IllegalStateException.

Điểm rất lớn mà tôi nên đề cập trước đó là: Tôi muốn cả hai phương pháp có thể sử dụng lại được. Nếu phương thứC# 1 tiếp tục cho đến khi kết thúc tệp và sau đó tôi sử dụng phương pháp # 2, tôi muốn đối tượng Máy quét đọc từ đầu tệp một lần nữa. Và có vẻ như cách duy nhất để làm điều này là để phục hồi đối tượng Scanner.

Khi tôi lần đầu tiên biết về I/O trong Java, tôi nhớ mình đã nói đến luôn hãy chắc chắn để đóng đối tượng Scanner khi bạn đã hoàn tất việc sử dụng chúng. Đó là cái gì đó đã được ăn sâu vào não của tôi gần như. Bất kể, làm thế nào để tôi có được điều này? Một suy nghĩ tôi đã có là để thiết lập scan để null ở phần cuối của cả hai phương pháp của tôi. Điều đó có cần thiết không? Tôi đã đọc trên các bài viết khác trong StackOverflow mà sẽ dẫn tôi đến thậm chí không đóng đối tượng Scanner của tôi và chỉ để cho các nhà sưu tập rác chăm sóc nó.

Ngoài tất cả điều này, tôi cũng tự hỏi chính xác những gì sẽ xảy ra với Máy quét khi nó được đóng và tại sao nó không thể mở lại được. Tôi hiểu rằng nó có liên quan đến các luồng, nhưng tôi không biết chính xác những gì trong ngữ cảnh của Java. Tôi đã cố gắng tìm kiếm các Stream class, nhưng đã không thể có được nhiều sự hiểu biết từ nó.

Đây là mã từ cả hai phương pháp của tôi:

Phương pháp # 1

public int numberOfLines(){ 
    try{ 
     if(scan.hasNext() == false || scan == null) 
      scan = new Scanner(new File(this.getFileName())); 
    } 
    catch(FileNotFoundException fnfe){ 
     System.err.println("The " + fileName + " could not be found."); 
    } 
    catch(IOException ioe){ 
     ioe.printStackTrace(); 
    } 

    int lineCount = 0; 
    while(scan.hasNextLine()){ 
     scan.nextLine(); 
     lineCount++; 
    } 
    scan.close(); 
    return lineCount; 
} 

Phương pháp # 2

public void readFile(FoodArrayList fal){ 
    try{ 
     if(scan.hasNext() == false || scan == null) 
      scan = new Scanner(new File(this.getFileName())); 
    } 
    catch(FileNotFoundException fnfe){ 
     System.err.println("The " + fileName + " could not be found."); 
    } 
    catch(IOException ioe){ 
     ioe.printStackTrace(); 
    } 

    while(scan.hasNextLine()){ 
     String stringRead = scan.nextLine(); 
     StringTokenizer tokens = new StringTokenizer(stringRead,","); 
     Food temp = new Food(); 
     temp.setCorpName(tokens.nextToken()); 
     temp.getContact().setLast(tokens.nextToken()); 
     temp.getContact().setFirst(tokens.nextToken()); 
     temp.setDate(tokens.nextToken()); 
     temp.setProductCode(tokens.nextToken()); 
     temp.setDescription(tokens.nextToken()); 
     temp.setReason(tokens.nextToken()); 
     String numberString = tokens.nextToken(); 
     int number = Integer.parseInt(numberString); 
     temp.setNumber(number); 
     temp.setCoP(tokens.nextToken()); 
     fal.insert((Food)temp); 
    } 
    scan.close(); 
} 

Tôi muốn giữ hai phương pháp riêng biệt. Điều này là do trong lớp khách hàng của tôi, tôi thực hiện như sau:

FoodArrayList list; 
    FileIO fio = new FileIO(); 
    int listSize = fio.numberOfLines();  
    list = new FoodArrayList(listSize);  
    fio.readFile(list); 

Trình tạo mặc định của lớp FileIO của tôi đã xem xét tệp cụ thể mà tôi đang cố gắng đọc. Tất nhiên, hàm tạo quá tải cho phép một hàm sử dụng một tên tệp khác làm đầu vào. Bất kỳ trợ giúp về điều này sẽ được đánh giá cao.

+1

'if (scan.hasNext() == false || scan == null)' bạn nên trao đổi các điều kiện, bởi vì nếu có khả năng 'đối tượng quét' là 'null' thì bạn nên kiểm tra nó trước. Ngoài ra, bạn chỉ cần phương thức đầu tiên nếu bạn đang lưu trữ các đối tượng 'Food' trong một mảng. Nhưng tôi đoán bạn đã sử dụng một số bộ sưu tập, không yêu cầu số lượng dòng. – YoungHobbit

+0

danh sách FoodArrayList là gì? chính xác những gì bạn muốn làm khi bạn gọi constructor của nó và vượt qua listize như là một đối số? –

+0

FoodArrayList là một lớp hoạt động giống như một đối tượng ArrayList, ngoại trừ việc nó được thiết kế để chỉ lưu trữ các đối tượng Thực phẩm. Tôi biết tôi có thể chỉ sử dụng một thể hiện của ArrayList, nhưng tôi có lý do của tôi để tạo ra lớp học đặc biệt này. Khi tôi chuyển listSize thành một đối số, về cơ bản tôi tạo một mảng các đối tượng Food với kích thước của listSize. – coolDude

Trả lời

2

Tôi muốn cả hai phương pháp có thể sử dụng lại được. Nếu phương thứC# 1 tiếp tục cho đến khi kết thúc tệp và sau đó tôi sử dụng phương pháp # 2, tôi muốn đối tượng Máy quét đọc từ đầu tệp một lần nữa. Và có vẻ như cách duy nhất để làm điều này là để phục hồi đối tượng Scanner.

Dường như bạn có câu trả lời ở đây. Bạn muốn khôi phục đối tượng Scanner bất kể trạng thái của một trong số đó có thể là gì, do đó, chỉ cần ... thực hiện điều đó.

Khi bắt đầu các phương pháp, hãy khai báo và khởi tạo tham chiếu Scanner của bạn. Bạn cũng có thể sử dụng try-with-resources để Scanner của bạn luôn đóng vào cuối thời gian chạy.

public void countLines() { 
    try(Scanner scan = new Scanner(new File("file.txt"))) { 
     // code 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

Mặc dù trong thực tế công việc bạn đang làm có thể được thực hiện trong cùng một phương pháp, nếu bạn nhấn mạnh vào việc thực hiện các hoạt động riêng rẽ, sau đó khởi tạo hai khác nhau Scanner s là lựa chọn tốt nhất của bạn.

+0

Tôi làm theo những gì bạn đang nói. Tuy nhiên, hai phương thức này là một phần của lớp FileIO. Trong các nhà xây dựng của tôi, tôi đã khởi tạo đối tượng Scanner của mình. – coolDude

+0

Có lẽ tôi hiểu nhầm điểm của bạn. . . Bạn đang nói đến việc thậm chí không sử dụng câu lệnh 'if' và khôi phục lại Máy quét bất kể? Bằng cách đó, nó sẽ không quan trọng như thế nào tôi định nghĩa các nhà xây dựng của tôi cho lớp FileIO bởi vì tôi muốn những phương pháp này để bắt đầu từ đầu của tập tin mỗi khi chúng được sử dụng. Và việc phục hồi đối tượng Scanner là cách duy nhất để bắt đầu từ lúc bắt đầu đọc tệp. – coolDude

+0

Và tôi muốn công việc được thực hiện theo hai phương pháp riêng biệt. Đó là vì trong lớp khách hàng của tôi, tôi có đoạn mã sau: 'danh sách FoodArrayList; ' ' FileIO fio = new FileIO(); ' ' int listSize = fio.numberOfLines();' 'list = new FoodArrayList (listSize); ' ' fio.readFile (danh sách); ' Rất khó để thấy điểm của tôi trong một nhận xét. Tôi có thể thêm mã này vào câu hỏi chính nếu bạn muốn. – coolDude

Các vấn đề liên quan