-1

我有一个需要解析的文件。虽然问题很简单,但我没有取得任何进展。问题如下。该文件包含大约 20-22 行的数据块,然后是未知数量的空白行,然后是 20-22 行的块。我需要为这些数据块制作数据结构。我试过以下

File f1 = new File(PATH_TO_TRAINING_FILE);
FileInputStream fis1 = new FileInputStream(f1);
readerTrainingFile = new BufferedReader(new InputStreamReader(fis1));
String trainLine;
while (( trainLine =readerTrainingFile.readLine()) != null) {
    ArrayList<String> train = new ArrayList<String>();
    while (!trainLine.trim().equals("")) {
        train.add(trainLine);
        trainLine =readerTrainingFile.readLine();
    }
    while (readerTrainingFile.readLine().trim().equals("")) {
    }
}

所以上面代码的问题是在第三个while循环中,当我完成对空行的检查时,读取行的指针移动到下一个块的第一个非空格行。因此,当我的控件到达第一个 while 循环时,它会跳过我想要的两行数据。如果这个问题真的很简单,我真的很抱歉。我现在坚持了2天。谢谢你的帮助。

4

5 回答 5

2

重构它,使该行在readerTrainingFile.readLine()您的程序中只出现一次。嵌套的 while 循环是让自己的生活变得悲惨的好方法。continue如果您需要跳过行,请使用语句。对于调试,System.out.println(trainLine)查看您正在阅读的内容并可能每次都跳过。这些步骤应该可以解决您的问题。

于 2012-12-04T23:06:06.027 回答
1

考虑这样的事情

List<List<String>> trains = new ArrayList<List<String>>();
List<String> curTrain = null;
while (( trainLine=readerTrainingFile.readLine()) != null) {
    if (!trainLine.trim().equals(""))
        curTrain = null;
    else 
    {
        if (curTrain == null)
        {
            curTrain = new ArrayList<String>();
            trains.add(curTrain);
        }
        curTrain.add(trainLine)
    }
}

trains是一个包含所有块的列表。读取数据时,curTrain指的是当前正在添加行的块。每次你得到一个非空行时,你将它添加到当前块中,但是如果没有当前块(因为你在开始,或者一个或多个之前的行是空白的)你创建一个新的并且将其添加到块列表中。

于 2012-12-04T23:20:24.457 回答
0
Scanner scanner = new Scanner(f1);
ArrayList<String> train = new ArrayList<String>();
while(scanner.hasNextLine()){
    String temp = scanner.nextLine();
    if(!temp.trim().equals(""))
        train.add(temp);
}

您可以用等效的缓冲阅读器替换scanner.hasNextLine

(temp = reader.nextLine()) != null

但是 Scanner 更易于使用 + 理解。您正在从第一个 while 循环中添加字符串,因此 arraylist 是本地的,并且在循环完成后不会持续存在(reader.nextLine() == null)。

请注意,您在同一类型上使用 != 和 !.equals() 。这对字符串很好,但通常 .equals 用于对象, == 用于基元(java 将字符串视为对象和基元之间的某处)。

于 2012-12-04T23:24:32.867 回答
0

我不知道那些“块”代表什么,但我会首先想象比字符串列表更好的抽象。

这是您可以解决的一种方法:

package cruft;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * FileChunkParser description here
 * @author Michael
 * @link
 * @since 12/4/12 6:06 PM
 */
public class FileChunkParser {

    public static void main(String[] args) {
        try {
            File f = new File((args.length > 0) ? args[0] : "resources/chunk.txt");
            Reader reader = new FileReader(f);
            FileChunkParser parser = new FileChunkParser();
            Map<Integer, List<String>> chunks = parser.parse(reader);
            for (int index : chunks.keySet()) {
                System.out.println(String.format("index: %d chunk: %s", index, chunks.get(index)));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Map<Integer, List<String>> parse(Reader reader) throws IOException {
        Map<Integer, List<String>> chunks = new TreeMap<Integer, List<String>>();
        BufferedReader br = null;
        try {
            if (reader != null) {
                br = new BufferedReader(reader);
                int chunkCount = 0;
                String line = "";
                List<String> chunk = null;
                while ((line = br.readLine()) != null) {
                    if (StringUtils.isBlank(line)) {
                        if (chunk != null) {
                            chunks.put(chunkCount++, new LinkedList<String>(chunk));
                            chunk = null;
                        }
                        continue;
                    } else {
                        if (chunk == null) {
                            chunk = new LinkedList<String>();
                        }
                        chunk.add(line);
                    }
                }
                if (chunk != null) {
                    chunks.put(chunkCount++, chunk);
                }
            }
        } finally {
            IOUtils.closeQuietly(reader);
        }
        return chunks;
    }
}

我用这个输入文件运行它:

this
is
how
you
do
it



see
how
it
handles
arbitrary
sized
chunks
with
any
blank
lines
between

try
it
and
see

这是输出:

index: 0 chunk: [this, is, how, you, do, it]
index: 1 chunk: [see, how, it, handles, arbitrary, sized, chunks, with, any, blank, lines, between]
index: 2 chunk: [try, it, and, see]
于 2012-12-04T23:26:38.253 回答
0
while (( trainLine =readerTrainingFile.readLine()) != null) {
            ArrayList<String> train = new ArrayList<String>();
            while (!trainLine.trim().equals("")) {
                train.add(trainLine);
                trainLine =readerTrainingFile.readLine();
            }
            while (readerTrainingFile.readLine().trim().equals("")) {

            }
 }

那是你的问题。你读了两遍。只需将此代码放在第一个while循环中:

if (trainLine.trim().equals("")) {
    train.add(trainLine);
}

另外,另一个问题:移动这个:

ArrayList<String> train = new ArrayList<String>();

跳出循环。否则每次阅读一行时都会创建一个新的。

于 2012-12-04T23:08:22.683 回答