【问题标题】:Read text file with repeated pattern into list将具有重复模式的文本文件读入列表
【发布时间】:2016-11-22 21:06:30
【问题描述】:

我正在尝试为 Java 创建一个 Tile Map Editor,但在文件打开时遇到了问题。打开文件本身并不是什么大问题,但是一旦我在文本文件中输入空格,它就会产生运行时错误。每个图块都包含一个图像(黑色或白色方形 atm)以及它是实心 (1) 还是非实心 (0)。瓦片地图当前将保存为如下格式:

1:1 1:1 1:1 1:1 1:1 1:1
1:1 0:0 0:0 0:0 0:0 1:1
1:1 0:0 0:0 0:0 0:0 1:1
1:1 1:1 1:1 1:1 1:1 1:1

例如,这可能是一个简单的房间,带有坚固的黑色墙壁并且会阻挡玩家。这将是一个 6x4 的瓦片地图。如何定义格式 x:x(whitespace here)?

List<Integer> list = new ArrayList<Integer>();
File file = new File("file.txt");
BufferedReader reader = null;
try 
{
    reader = new BufferedReader(new FileReader(file));
    String text = null;
    while ((text = reader.readLine()) != null) 
    {
    list.add(Integer.parseInt(text));
    }
}
catch (FileNotFoundException e) 
{
    e.printStackTrace();
}
catch (IOException e) 
{
    e.printStackTrace();
}

【问题讨论】:

  • 您究竟想在列表的每个元素中存储什么?单个 1:1 还是整行?当您尝试在充满冒号的行上进行 parseInt 时,会发生异常。您为什么要在包含冒号的这一行上尝试 parseInt ?如果您想解析出您的 int,那么您希望列表中的每个元素看起来像什么?
  • 上面的代码示例是为了尝试使其在更基础的层面上工作。在实际情况下,我有一个 List TileMap。 Tile 是一个由 int ID 和 int Type 及其 getters() 和 setters() 组成的类。因此,我想将第一个 1 存储为 ID,将第二个 1 存储为类型,并像列表中的每个 Tile 元素一样继续。编辑:我正在寻找的就像 c# scanf Arguments %d or %r etc...

标签: java file format delimiter file-handling


【解决方案1】:

虽然猜测这就是您要的,但类似这样的东西......

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ReadTextFile {

    public static void main(String[] args) {
        List<Tile> list = new ArrayList<Tile>();
        String path = "C:/whatever/your/path/is/";
        File file = new File(path + "file.txt");
        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
            String text = null;
            while ((text = reader.readLine()) != null) {
                String[] pairs = text.split(" ");
                for(String pair : pairs) {
                    String[] chars = pair.split(":");
                    int id = Integer.parseInt(chars[0]);
                    int type = Integer.parseInt(chars[1]);
                    list.add(new Tile(id, type));
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } 

    }
}

class Tile {
    int id;
    int type;

    Tile(int id, int type) {
        this.id = id;
        this.type = type;
    }

    @Override
    public String toString() {
        return "Tile [id=" + id + ", type=" + type + "]";
    }


}

【讨论】:

  • 完美!几乎可以一对一地实现它。我将花时间修改流和它们的可能性:) 唯一需要改变的是程序识别 txt 文件中的行尾。我想我可以用一个十六进制编辑器来做到这一点,它会告诉我什么样的字符用于换行符,然后在我的程序中检查它。谢谢!
  • 还有一件事:我不应该关闭 BufferedReader 吗?
  • BufferedReader 自动关闭。请注意它是如何使用 try-with-resources 实现(自 JDK7 起可用)实例化的。另外,请注意 BufferedReader 实现了 AutoCloseable;任何实现 AutoCloseable 的东西都可以在 try-with-resources 语句中使用。是的,使用 Streams 会很棒。
【解决方案2】:

如果您只是被空格困扰,请将代码更改为

 while ((text = reader.readLine()) != null) 
{
    list.add(Integer.parseInt(text.trim()));
}

但我认为这不起作用,因为您无法将整行转换为整数,所以我建议:

 while ((text = reader.readLine()) != null) 
{
    String[] values = text.split(":")
    for(String val : values)
    {
        list.add(Integer.parseInt(val.trim()));
    }
}

【讨论】:

  • 谢谢你让我走上了正轨。就像我在上面的评论中所说的那样,我只需要找出 bufferedreader 是如何知道 txt 文件中的行何时完成的。
猜你喜欢
  • 1970-01-01
  • 2013-09-19
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多