【问题标题】:Read CSV file and use StringTokenizer读取 CSV 文件并使用 StringTokenizer
【发布时间】:2014-04-20 04:48:29
【问题描述】:

这是一个简单的家庭作业,过去几天一直让我发疯。如果我要使用几个数组,我可以在不久前完成它,但不得不使用 StringTokenizer 让我发疯。

我遇到的主要问题是读取 CSV 文件。我不知道该怎么做,以前的在线搜索只提出了超级激烈的解决方案,对于像我这样的初学者来说太过分了。

这是我的代码。如您所见,我不知道是使用.nextLine() 还是.NextToken()。两者似乎都不起作用。

对于那些想知道作业的人来说,基本上是读取前 4 个用逗号分隔的产品,然后读取其余行作为这 4 个产品的评分。基本上6行4列。第一行是产品,其余的是评分。

import java.util.StringTokenizer;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class ProductRating {

public static void main(String[] args) {
    // TODO Auto-generated method stub


    Scanner fileIn=null;
    try{
        fileIn = new Scanner(
                 new FileInputStream("C:/Users/Cristian/Desktop"));
    }
    catch (FileNotFoundException e)
     {  // This block executed if the file is not found
        // and then the program exits
    System.out.println("File not found.");
    System.exit(0);
    }

    //If Opened File Successful this runs
    String products = "A";
    String rantings ="0";
    System.out.println("Gathering Ratings for Products");

    do{

        String delimiters = ", ";

        StringTokenizer gatherProducts[]=new StringTokenizer[inputLine, delimeters];
        gatherProducts=fileIn.nextLine();

    }while(fileIn.hasNextLine()==true);

}   

}

【问题讨论】:

  • +1 这是关于家庭作业的问题。
  • 字符串标记器已被贬值,我很惊讶老师会要求您使用它。拆分是现在的事情。
  • 小心,CSV 不仅仅是分隔符。你也有转义字符。
  • @Marichyasana 不鼓励使用StringTokenizer,但不建议使用。
  • 不管怎样,为什么会出现这个问题

标签: java string csv tokenize


【解决方案1】:

在 java 8 中使用Streams API 的简单方法(带有标题行的 csv):

Path path = Paths.get("C:/Users/Cristian/Desktop"); // path to folder
    Path file = path.resolve("file.csv"); // filename 
    Stream<String> lines = Files.lines(file);
    List<String[]> list = lines
            .skip(1)
            .map(line -> line.split(","))
            .collect(Collectors.toList());

您还可以使用flatMap 函数检索单个列表中的所有元素

         List<String> list = lines
            .skip(1)
            .map(line -> line.split(","))
            .flatMap(Arrays::stream)
            .collect(Collectors.toList());

【讨论】:

  • @Cristian Reyes 你使用 java 8 吗?你试过我的答案了吗?
【解决方案2】:

为什么要使用 StringTokenizer 数组?试试这个。

try{
            StringTokenizer st=null;
            FileReader inputFileReader = new FileReader("C:/Users/Cristian/Desktop");
            BufferedReader inputStream = new BufferedReader(inputFileReader);
            String inLine = null;
            while((inLine =  inputStream.readLine())!=null){
                st = new StringTokenizer(inLine, ",");
                System.out.println(st.nextToken());
                System.out.println(st.nextToken());
                System.out.println(st.nextToken());
            }
        }
        catch (FileNotFoundException e)
         {  // This block executed if the file is not found
            // and then the program exits
        System.out.println("File not found.");
        System.exit(0);
        }

【讨论】:

  • 在 while 行中告诉我“未处理的异常类型 IOexception”。
【解决方案3】:

首先,我认为您没有正确解释 StringTokenizer 方法调用/返回类型。数组对我来说没有多大意义。

您想遍历 csv 文件中的每一行,对吗?您可以在循环的每一步创建一个新的StringTokenizer,然后使用它从每一行中获取您想要的内容。

清理您的 do ... while 循环,使其看起来更像这样:

final String delimiter = ", ";
for(int lineNumber = 1; fileIn.hasNextLine(); ++lineNumber) {
    String csvLine = fileIn.next();
    if (lineNumber == 1) {
      // this is your special case for the first line, handle it!
      continue;
    }

    StringTokenizer tokenizer = new StringTokenizer(csvLine, delimiter);
    while (tokenizer.hasMoreTokens()) {
      String token = tokenizer.nextToken();
      // do stuff with the tokens!
    }
}

【讨论】:

  • 如何拆分行?我试图自己获取第一行并尝试使用 .substring() 但这没有用。我需要从其余行中获取评级,将它们转换为数字,然后对它们进行平均。知道怎么做吗?
  • 我已经更新了答案,包括第一行的特殊情况。请记住,文件中的每一行文本都对应于 java 中的一个字符串。这就是扫描仪在这里的用途。
【解决方案4】:

使用SuperCSV,示例如下,来自this page

private static void readWithCsvBeanReader() throws Exception {

        ICsvBeanReader beanReader = null;
        try {
                beanReader = new CsvBeanReader(new FileReader(CSV_FILENAME), CsvPreference.STANDARD_PREFERENCE);

                // the header elements are used to map the values to the bean (names must match)
                final String[] header = beanReader.getHeader(true);
                final CellProcessor[] processors = getProcessors();

                CustomerBean customer;
                while( (customer = beanReader.read(CustomerBean.class, header, processors)) != null ) {
                        System.out.println(String.format("lineNo=%s, rowNo=%s, customer=%s", beanReader.getLineNumber(),
                                beanReader.getRowNumber(), customer));
                }

        }
        finally {
                if( beanReader != null ) {
                        beanReader.close();
                }
        }
}

您需要为您的业务对象定义一个bean,并使用它来代替 CustomerBean。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多