9

我正在编写解析器代码来读取 .csv 文件并将其解析为 XML。这是我拥有的代码,它可以工作,除了我希望它跳过文件中的第一行。所以我决定设置一个 HashMap 但它似乎不起作用:

for (int i = 0; i < listOfFiles.length; i++) {
        File file = listOfFiles[i];
        if (file.isFile() && file.getName().endsWith(".csv")){
        
            System.out.println("File Found: " + file.getName());//Prints the name of the csv file found

            String filePath = sourcepath + "\\" + file.getName();

            BufferedReader br = new BufferedReader(new FileReader(file));  


String line;
int n = 1;
Map<Integer,String> lineMap = new HashMap<Integer,String>();
int k=2;
while ((line = br.readLine()) != null) {
    System.out.println(n + " iteration(s) of 1st While Loop");
    
                    lineMap.put(k, line);

    fw.write("          <ASSET action=\"AddChange\">\n");
    fw.write("              <HOSTNAME>\n");
    hostName=line.substring(0, line.indexOf(","));
    fw.append(hostName);
    fw.write("</HOSTNAME>\n");
    fw.write("              <HOSTID>\n");
    hostID=line.substring(line.indexOf(",")+1, nthOccurrence(line, ',', 1));
    fw.append(hostID);
    fw.write("</HOSTID>\n");
    fw.write("              <MACMODEL>\n");
    machineModel=line.substring(nthOccurrence(line, ',', 1)+1, nthOccurrence(line, ',', 2));
    fw.append(machineModel);
    fw.write("</MACMODEL>\n");
    fw.write("              <PROMODEL>\n");
    processorModel=line.substring(nthOccurrence(line, ',', 2)+1, nthOccurrence(line, ',', 3));
    fw.append(processorModel);
    fw.write("</PROMODEL>\n");
    fw.write("              <CORE>\n");
    core=line.substring(nthOccurrence(line, ',', 3)+1, nthOccurrence(line, ',', 4));
    fw.append(core);
    fw.write("</CORE>\n");
    fw.write("              <PROC>\n");
    proc=line.substring(nthOccurrence(line, ',', 4)+1, nthOccurrence(line, ',', 5));
    fw.append(proc);
    fw.write("</PROC>\n");
    fw.write("              <TIER>\n");
    tier=line.substring(nthOccurrence(line, ',', 5)+1, nthOccurrence(line, ',', 6));
    fw.append(tier);
    fw.write("</TIER>\n");
    fw.write("              <PRODNAME>\n");
    productName=line.substring(nthOccurrence(line, ',', 6)+1, nthOccurrence(line, ',', 7));
    fw.append(productName);
    fw.write("</PRODNAME>\n");
    fw.write("              <VERSION>\n");
    version=line.substring(nthOccurrence(line, ',', 7)+1, nthOccurrence(line, ',', 8));
    fw.append(version);
    fw.write("</VERSION>\n");
    fw.write("              <SCRIPTDATA>\n");
    scriptData=line.substring(nthOccurrence(line, ',', 8)+1, line.length());
    fw.append(scriptData);
    fw.write("</SCRIPTDATA>\n");
    

  fw.write("            </ASSET>\n");
  k++;
}n++;

这是代码主要部分的片段。任何想法或解决方案???

4

9 回答 9

30

您可能会考虑headerLine = br.readLine()在 while 循环之前放置,以便将标头与文件的其余部分分开使用。您也可以考虑使用opencsv进行 csv 解析,因为它可以简化您的逻辑。

于 2013-08-19T04:18:58.623 回答
12

我觉得有必要添加一个 java 8 风格的答案。

List<String> xmlLines = new BufferedReader(new FileReader(csvFile))
    .lines()
    .skip(1) //Skips the first n lines, in this case 1      
    .map(s -> {
        //csv line parsing and xml logic here
        //...
        return xmlString;
    })
    .collect(Collectors.toList());
于 2016-02-24T12:27:08.597 回答
6

创建一个变量interation并用 初始化0while检查它作为循环中的第一件事。

String line;
int iteration = 0;
while ((line = br.readLine()) != null) {
    if(iteration == 0) {
        iteration++;  
        continue;
    }
    ...
    ...
}
于 2013-08-19T04:16:34.930 回答
2

我对你的代码感到很困惑,你有 lineMap 并且你也有 fw (不管是什么)。你用的是哪一个?你说你想跳过第一行,但你没有

if (firstLine == true) {
   firstLine = false;
   continue;
}

我还建议使用像 CSVReader 这样的库,我相信它甚至有一个属性 ignoreFirstLine

http://opencsv.sourceforge.net/apidocs/au/com/bytecode/opencsv/CSVReader.html

于 2013-08-19T04:17:25.110 回答
2

为什么不直接使用 for 循环

for(int i=1; (line = br.readLine()) != null; i++)
{
    //Your code
}
于 2013-08-19T04:18:28.960 回答
1

一种简单的技术,声明一个变量并为其分配一个值(例如int k = 0;),然后在您进入循环后立即增加变量值。代码如下。

BufferedReader csvReader = new BufferedReader(new FileReader("mycsv.csv"));
        // declare a variable
        int k=0;
        while ((row = csvReader.readLine()) != null) {
            if(k == 0){
                k++;
                continue;
            }
         //rest of your code 
         // inside while loop
        }
于 2021-06-10T21:35:34.120 回答
0

使用缓冲区读取器两次,如下所示:

while ((line = br.readLine()) != null) {
  while ((line = br.readLine()) != null) {
    //your code                     
  }
}
于 2014-03-14T07:33:20.570 回答
0
boolean isRecord = false;
for (CSVRecord record : records) {
    if(isRecord){
        //process records here.
    }else{
        isRecord = true;
    }
}

而不是添加计数器添加标志不会影响性能。

于 2016-12-03T04:38:39.603 回答
-1

对于跳过第一行(通常包含列的标题),取一个变量并首先在 while 循环中增加这个变量,然后继续;

int lineNumber = 0;

and then in while loop 

while ((line = br.readLine()) != null) {
                        if(lineNumber == 0) {
                            lineNumber++;
                            continue;
                        }
                        lineNumber++;

                       //do waterver u have to do with the tokens in this line(second line)

            }
于 2014-09-05T06:37:33.683 回答