Java食物日记项目开发疑问:Scanner关闭位置咨询
Great question! When dealing with resources like Scanner, it’s crucial to close them properly to avoid system resource leaks. The best approach here is to use try-with-resources (introduced in Java 7), which automatically closes any resources that implement AutoCloseable (like Scanner and PrintWriter) once the block finishes executing—no need to manually call close()!
Example Implementation for Your Food Diary
Here’s how to structure your code to handle input, write to CSV, and manage resources correctly:
import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.util.Scanner; public class FoodDiaryApp { public static void main(String[] args) { // Use try-with-resources for Scanner and PrintWriter to auto-close them try (Scanner userInput = new Scanner(System.in); PrintWriter writer = new PrintWriter(new File("food_diary.csv"), "UTF-8")) { // Check if file is empty to write header only once File diaryFile = new File("food_diary.csv"); if (diaryFile.length() == 0) { writer.println("Meal Type,Food Item,Calories"); // CSV header } // Collect user input for each meal collectMealEntries(userInput, writer, "Breakfast"); collectMealEntries(userInput, writer, "Lunch"); collectMealEntries(userInput, writer, "Dinner"); collectMealEntries(userInput, writer, "Snacks"); System.out.println("Food diary entries saved successfully!"); } catch (FileNotFoundException e) { System.err.println("Error accessing the food diary file: " + e.getMessage()); } catch (Exception e) { System.err.println("An unexpected error occurred: " + e.getMessage()); } // No need to close Scanner/PrintWriter here—try-with-resources does it automatically! } private static void collectMealEntries(Scanner scanner, PrintWriter writer, String mealType) { System.out.println("\nEnter entries for " + mealType + " (type 'done' when finished):"); while (true) { System.out.print("Food item: "); String foodItem = scanner.nextLine().trim(); if (foodItem.equalsIgnoreCase("done")) { break; } System.out.print("Calories: "); int calories = scanner.nextInt(); scanner.nextLine(); // Consume the remaining newline character // Write to CSV (handle commas in food items by wrapping in quotes) String formattedItem = foodItem.contains(",") ? "\"" + foodItem + "\"" : foodItem; writer.println(mealType + "," + formattedItem + "," + calories); } } }
Why Try-With-Resources?
- It eliminates the need to remember to call
close()manually. - Resources are closed even if an exception is thrown during input or file writing.
- It makes your code cleaner and less error-prone.
If You Prefer Manual Closing
If you’re working with an older Java version that doesn’t support try-with-resources, you should close the Scanner in a finally block to ensure it’s closed regardless of exceptions:
public static void main(String[] args) { Scanner userInput = null; PrintWriter writer = null; try { userInput = new Scanner(System.in); writer = new PrintWriter(new File("food_diary.csv"), "UTF-8"); // Your input collection logic here... } catch (FileNotFoundException e) { // Handle exception } finally { if (userInput != null) { userInput.close(); // Close Scanner here after all input operations } if (writer != null) { writer.close(); } } }
In this case, you’d close the Scanner after you’ve finished all input operations—usually at the end of your program, inside the finally block to guarantee execution.
内容的提问来源于stack exchange,提问作者Blake Perrotte

