读取制表符分隔文件并忽略空格

时间:2016-05-24 04:26:05

标签: java

我正在开发一个简单的项目,其中以制表符分隔的文本文件被读入程序。

我的问题: 在读取文本文件时,通常会有空数据空间。缺乏数据导致意外输出。对于令牌[4]位置中没有数据的行,忽略所有读取的数据,并在运行System.out.println时显示“4”(只是测试正确读取数据)。当我在令牌[4]位置中包含一个值时,数据读取正常。我在令牌[4]位置输入一个值是不可接受的。请参阅下面的文件和代码。

2014    Employee    Edward Rodrigo  6500
2014    Salesman    Patricia Capola 5600    5000000
2014    Executive   Suzy Allen  10000   55
2015    Executive   James McHale    12500   49
2015    Employee    Bernie Johnson  5500    
2014    Salesman    David Branch    6700    2000000
2015    Salesman    Jonathan Stein  4600    300000
2014    Executive   Michael Largo   17000   50
2015    Employee    Kevin Bolden    9200    
2015    Employee    Thomas Sullivan 6250    

我的代码是:

// Imports are here
import java.io.*;
import java.util.*;

public class EmployeeData {

public static void main(String[] args) throws IOException {
    // Initialize variables
    String FILE = "employees.txt";  // Constant for file name to be read
    ArrayList<Employee> emp2014;    // Array list for 2014 employees
    ArrayList<Employee> emp2015;    // Array list for 2015 employees
    Scanner scan;

    // Try statement for error handling
    try {
        scan = new Scanner(new BufferedReader(new FileReader(FILE)));
        emp2014 = new ArrayList();
        emp2015 = new ArrayList();

        // While loop to read FILE
        while (scan.hasNextLine()) {
            String l = scan.nextLine();
            String[] token = l.split("\t");
            try {
                String year = token[0];
                String type = token[1];
                String name = token[2];
                String monthly = token[3];
                String bonus = token[4];
                System.out.println(year + " " + type + " " + name + " " + monthly + " " + bonus);
            } catch (Exception a) {
                System.out.println(a.getMessage());
            }
        }
    } catch(Exception b) {
        System.out.println(b.getMessage());
    }
}

}

我收到的带有“员工”的行的输出以意想不到的方式返回。

输出:

run:
4
2014 Salesman Patricia Capola 5600 5000000
2014 Executive Suzy Allen 10000 55
2015 Executive James McHale 12500 49
4
2014 Salesman David Branch 6700 2000000
2015 Salesman Jonathan Stein 4600 300000
2014 Executive Michael Largo 17000 50
4
4
BUILD SUCCESSFUL (total time: 0 seconds)

我尝试使用if-then来测试令牌[4]位置的空值,但这对我没有帮助。我做了很多搜索但没有成功。

我对编程世界还很陌生,所以请原谅我的编码效率低下。非常感谢任何支持和一般反馈,以提高我的技能!

谢谢你, 布赖恩

2 个答案:

答案 0 :(得分:0)

这种情况正在发生,因为您实际上正在收到ArrayOutOfBoundsException,并且该消息是&#39; 4&#39;。因为索引4大于数组的长度。您应该输入catch语句b.printStackTrace(),因为这会在发生捕获的异常时为您提供更多详细信息。

您可以通过添加以下内容来解决此问题:

String bonus = "";
if(token.length > 4)
    bonus = token[4];

答案 1 :(得分:0)

由于ArrayOutOfBoundsException,Java Devil是正确的基础问题。但它也值得探索为什么你没有看到这一点。正如我们在评论中所讨论的,您的“错误处理的Try语句”实际上根本不处理您的错误,而是suppressing them,这通常是一个糟糕的计划,因为它允许您的程序继续运行,即使您的假设(它正常工作)已被违反。

这是一个稍微清理过的代码版本。导致ArrayOutOfBoundsException的潜在问题仍然存在,但如果您以这种方式构建代码,问题就会立即显现出来。有一些评论内联提出问题。

public class EmployeeData {
  // constants should be declared static and final, and not inside main
  private static final String FILE = "employees.txt";

  // If you have an exception and you don't know how to handle it the best thing
  // to do is throw it higher and let the caller of your method decide what to do.
  // If there's *nothing* you want to do with an exception allow main() to throw
  // it as you do here; your program will crash, but that's a good thing!
  public static void main(String[] args) throws IOException {
    // Notice the <> after ArrayList - without it you're defining a "raw type"
    // which is bad - https://stackoverflow.com/q/2770321/113632
    ArrayList<Employee> emp2014 = new ArrayList<>();
    ArrayList<Employee> emp2015 = new ArrayList<>();

    // A try-with-resources block automatically closes the file once you exit the block
    // https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
    try (Scanner scan = new Scanner(new BufferedReader(new FileReader(FILE)))) {
      while (scan.hasNextLine()) {
        String l = scan.nextLine();
        String[] token = l.split("\t");
        // The code below this line assumes that token has at least five indicies;
        // since that isn't always true you need to handle that edge case before
        // accessing the array indicies directly.
        String year = token[0];
        String type = token[1];
        String name = token[2];
        String monthly = token[3];
        String bonus = token[4];
        System.out.println(year + " " + type + " " + name + " " + monthly + " " + bonus);
      }
    }
  }
}