简体   繁体   English

使用扫描仪类错误读取CSV文件

[英]Reading CSV File Using Scanner Class Error

I have an original code that came from a Java book example. 我有一个来自Java图书示例的原始代码。 The program simply reads a text file ("clients.txt"). 该程序仅读取一个文本文件(“ clients.txt”)。 However, I would like to modify the "clients.txt" into a "clients.csv" and have the program read ".csv" file instead. 但是,我想将“ clients.txt”修改为“ clients.csv”,并让程序读取“ .csv”文件。 I have parsed the data with "," as the delimiter according to this format and added/updated two lines of code in the ReadTextFile.java file below only: 我已经按照这种格式用“,”作为分隔符来解析数据,并且仅在下面的ReadTextFile.java文件中添加/更新了两行代码:

Added/updated Code: 添加/更新的代码:

input = new Scanner( new File( "clients.csv" ) );
input.useDelimiter(",");    

Thought that this is a simple modification from reading a .txt file to a .csv file, I got a NoSuchElementException or File improperly formed print message. 以为这是从读取.txt文件到.csv文件的简单修改,我收到了NoSuchElementExceptionFile improperly formed .csv File improperly formed打印消息。

I know that there are other classes that I can use such as BufferedReader and/or CsvReader Class but just wanted to figure out why input.useDelimiter() method is not working here. 我知道还有其他一些类可以使用,例如BufferedReader和/或CsvReader类,但只是想弄清楚为什么input.useDelimiter()方法在这里不起作用。

===================== =====================

Error Message 错误信息

Process started >>>
<<< Process finished. (Exit code 0)
java ReadTextFileTest
Process started >>>
Account   First Name  Last Name      Balance
File improperly formed.
<<< Process finished. (Exit code 1)

===================== =====================

ReadTextFile.java ReadTextFile.java

import java.io.File;
import java.io.FileNotFoundException;
import java.lang.IllegalStateException;
import java.util.NoSuchElementException;
import java.util.Scanner;

public class ReadTextFile
{
   private Scanner input;

   public void openFile()
   {
      try
      {

         // Orig code: input = new Scanner( new File( "clients.txt")    
         input = new Scanner( new File( "clients.csv")); // added/updated
         input.useDelimiter(",");                          // added 

      } 
      catch ( FileNotFoundException fileNotFoundException )
      {
         System.err.println( "Error opening file." );
         System.exit( 1 );
      } 
   } 


   public void readRecords()
   {

      AccountRecord record = new AccountRecord();

      System.out.printf( "%-10s%-12s%-12s%10s\n", "Account",
     "First Name", "Last Name", "Balance" );

      try 
      {
         while ( input.hasNext() )
         {
            record.setAccount( input.nextInt() ); // read account number
            record.setFirstName( input.next() ); // read first name
            record.setLastName( input.next() ); // read last name
            record.setBalance( input.nextDouble() ); // read balance

            System.out.printf( "%-10d%-12s%-12s%10.2f\n",
           record.getAccount(), record.getFirstName(),
           record.getLastName(), record.getBalance() );
         } 
      } 
      catch ( NoSuchElementException elementException )
      {
         System.err.println( "File improperly formed." );
         input.close();
         System.exit( 1 );
      } 
      catch ( IllegalStateException stateException )
      {
         System.err.println( "Error reading from file." );
         System.exit( 1 );
      } 
   } 

   public void closeFile()
   {
      if ( input != null )
         input.close(); 
   } 
} 

===================== =====================

ReadTextFileTest.java ReadTextFileTest.java

public class ReadTextFileTest
{
   public static void main( String args[] )
   {
      ReadTextFile application = new ReadTextFile();

      application.openFile();
      application.readRecords();
      application.closeFile();
   } 
} 

===================== =====================

AccountRecord.java AccountRecord.java

public class AccountRecord
{
   private int account;
   private String firstName;
   private String lastName;
   private double balance;

   public AccountRecord() 
   {
      this( 0, "", "", 0.0 );
   } 

   public AccountRecord( int acct, String first, String last, double bal)
   {
      setAccount( acct );
      setFirstName( first );
      setLastName( last );
      setBalance( bal );
   } 
   public void setAccount( int acct ) { account = acct; } public int getAccount() { return account; }

   public void setFirstName( String first )
   {
      firstName = first;
   } 
   public String getFirstName() 
   { 
      return firstName; 
   } 
   public void setLastName( String last )
   {
      lastName = last;
   } 
   public String getLastName() 
   {
      return lastName; 
   } 
   public void setBalance( double bal )
   {
      balance = bal;
   } 
   public double getBalance() 
   { 
      return balance; 
   } 
} 

=========================== ==========================

clients.txt (original file) clients.txt(原始文件)

100 Bob Jones 24.98
200 Steve Doe -345.67
300 Pam White 0.00
400 Sam Stone -42.16
500 Sue Rich 224.62
100 Bob Jones -4.98    
200 Steve Doe 45.67

=============================================== ==============================================

clients.csv (change from ".txt" to ".csv" file) clients.csv(从“ .txt”更改为“ .csv”文件)

100,Bob,Jones,24.98
200,Steve,Doe,-345.67
300,Pam,White,0.00
400,Sam,Stone,-42.16
500,Sue,Rich,224.62
100,Bob,Jones,-4.98
200,Steve,Doe,45.67

Your code fails when it tries to read the first balance. 您的代码尝试读取第一个余额时失败。 Since your delimiter is only a comma ( , ). 由于您的定界符只是一个逗号( , )。 It tries to read 24.98<new-line>200 as a double. 它尝试将24.98<new-line>200读取为双精度。

We can use a comma and a new line character as delimiters using a Pattern . 我们可以使用Pattern将逗号和换行符用作分隔符。

import java.util.regex.Pattern;

Pattern delimiter = Pattern.compile(",|\\s"); 
input = new Scanner(new File("clients.csv")).useDelimiter(delimiter);

There are some trailing spaces on a line of your files, so I used ,|\\\\s otherwise you can use ,|\\n or ,|\\n|\\r\\n . 文件的一行上有一些尾随空格,因此我使用了,|\\\\s否则可以使用,|\\n,|\\n|\\r\\n

Your CSV file must be: 您的CSV文件必须为:

100,Bob,Jones,24.98,200,Steve,Doe,-345.67,300,Pam,White,0.00,400,Sam,Stone,-42.16,500,Sue,lastName,0.00  

Your CSV file cannot contain \\n (linebreaks) as it will be an illegal character for your program. 您的CSV文件不能包含\\n (换行符),因为它将是程序的非法字符。 Coz your delimiter is , and not \\n . 因为您的定界符是,而不是\\n

But to keep your clients.csv file as it is, you can use the following method: 但是,要保持您的clients.csv文件不变,可以使用以下方法:

input.useDelimiter(Pattern.compile(",|\\n|\\r"));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM