JAVA 读取文本文件,计算数字并将其写入 Jtable

JAVA read text files, count numbers and write it to Jtable

我还在学习JAVA,几天来一直在尝试为我的程序寻找解决方案,但我还没有解决它。

我有很多文本文件(我的程序保存)。文件如下所示:

text (tab) number (tab) number (tab)...
text (tab) number (tab) number (tab)...

(tab)表示有制表符, text 表示是文本(字符串), number表示有数字(整数)。

文件数量可以从 1 到 32,文件名称如下:january1; 1月2日;一月 3...

我需要读取所有这些文件(忽略字符串)并仅对数字求和,如下所示:

while ((line = br.readLine()) != null) {

    counter=counter+1;
    String[] info = line.split("\s+");

    for(int j = 2; j < 8; j++) {

        int num = Integer.parseInt(info[j]);
        data[j][counter]=data[j][counter]+num;

    }

};

只是我想将所有 "tables" 求和到数组的数组(或任何类似类型的变量),然后将其显示为 table。如果有人知道任何解决方案或可以link任何类似的计算,那就太棒了!

我从该位置获取了所有 january1 january2... 文件,并使用相同的函数计算要存储的值。

然后我用两个 headers、DayNumber 创建了一个 table。然后根据生成的值添加行。

DefaultTableModel model = new DefaultTableModel();
JTable table = new JTable(model);
String line;

model.addColumn("Day");
model.addColumn("Number");
BufferedReader br = null;
model.addRow(new Object[]{"a","b"});

for(int i = 1; i < 32; i++)
{
try {

    String sCurrentLine;
    String filename = "january"+i;
    br = new BufferedReader(new FileReader("C:\january"+i+".txt"));
    int counter = 0;
    while ((sCurrentLine = br.readLine()) != null) {
        counter=counter+1;
        String[] info = sCurrentLine.split("\s+");
        int sum = 0;
        for(int j = 2; j < 8; j++) {

            int num = Integer.parseInt(info[j]);
            sum += num;

        }
        model.addRow(new Object[]{filename, sum+""});

    }

} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        if (br != null)br.close();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    }
}
JFrame f = new JFrame();
f.setSize(300, 300);
f.add(new JScrollPane(table));
f.setVisible(true);

使用标记循环和 Try-Catch。下面一块将所有数字添加到一行中。

你可以从这里得到一些提示:

String line = "text 1   2   3   4   del";
String splitLine[] = line.split("\t");
int sumLine = 0;
int i = 0;

contSum: for (; i < splitLine.length; i++) {
    try {
        sumLine += Integer.parseInt(splitLine[i]);
    } catch (Exception e) {
        continue contSum;
    }
}
System.out.println(sumLine);

这是另一个使用向量的例子。在此示例目录中,将搜索“.txt”文件并添加到 JTable。

doIt 方法将获取文本文件所在的文件夹。 然后这将递归,在文件夹中查找文件。 找到的每个文件都将按照您的示例文件进行拆分和添加。

public class FileFolderReader
{
  private Vector<Vector> rows = new Vector<Vector>();


  public static void main(String[] args)
  {
    FileFolderReader fileFolderReader = new FileFolderReader();
    fileFolderReader.doIt("D:\folderoffiles");

  }

  private void doIt(String path)
  {
    System.out.println(findFile(new File(path)) + " in total");
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Vector<String> columnNames = new Vector<String>();
    columnNames.addElement("File Name");
    columnNames.addElement("Size");

    JTable table = new JTable(rows, columnNames);

    JScrollPane scrollPane = new JScrollPane(table);
    frame.add(scrollPane, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
  }

  private int findFile(File file)
  {
    int totalPerFile = 0;
    int total = 0;
    File[] list = file.listFiles(new FilenameFilter()
    {
      public boolean accept(File dir, String fileName)
      {
        return fileName.endsWith(".txt");
      }
    });
    if (list != null)
      for (File textFile : list)
      {
        if (textFile.isDirectory())
        {
          total = findFile(textFile);
        }
        else
        {
          totalPerFile = scanFile(textFile);
          System.out.println(totalPerFile + " in " + textFile.getName());
          Vector<String> rowItem = new Vector<String>();
          rowItem.addElement(textFile.getName());
          rowItem.addElement(Integer.toString(totalPerFile));
          rows.addElement(rowItem);
          total = total + totalPerFile;
        }
      }
    return total;
  }

  public int scanFile(File file)
  {
    int sum = 0;
    Scanner scanner = null;
    try
    {
      scanner = new Scanner(file);

      while (scanner.hasNextLine())
      {
        String line = scanner.nextLine();
        String[] info = line.split("\s+");
        int count = 1;
        for (String stingInt : info)
        {
          if (count != 1)
          {
            sum = sum + Integer.parseInt(stingInt);
          }
          count++;
        }
      }
      scanner.close();
    }
    catch (FileNotFoundException e)
    {
      // you will need to handle this
      // don't do this !
      e.printStackTrace();
    }
    return sum;
  }
}

所以,据我所知,您有四个问题需要回答,这有悖于提问 A 问题的网站礼仪,但会试一试

  1. 如何列出一系列文件,大概使用某种过滤器
  2. 如何以某种有意义的方式读取文件和处理数据
  3. 如何管理数据结构中的数据
  4. JTable 中显示数据。

列出文件

可能列出文件的最简单方法是使用 File#list 并传递满足您需要的 FileFilter

File[] files = new File(".").listFiles(new FileFilter() {
    @Override
    public boolean accept(File pathname) {
        return pathname.getName().toLowerCase().startsWith("janurary");
    }
});

现在,我将编写一个方法,该方法使用一个 File 对象来表示您要列出的目录,并使用一个 FileFilter 来搜索它...

public File[] listFiles(File dir, FileFilter filter) throws IOException {
    if (dir.exists()) {
        if (dir.isDirectory()) {
            return dir.listFiles(filter);
        } else {
            throw new IOException(dir + " is not a valid directory");
        }
    } else {
            throw new IOException(dir + " does not exist");
    }
}

这样您就可以根据不同的 FileFilter 搜索一组不同的文件。

当然,您也可以使用较新的 Paths/Files API 来查找文件

正在读取文件...

读取多个文件归结为同一件事,读取单个文件...

// BufferedReader has a nice readline method which makes
// it easier to read text with.  You could use a Scanner
// but I prefer BufferedReader, but that's me...
try (BufferedReader br = new BufferedReader(new FileReader(new File("...")))) {
    String line = null;
    // Read each line
    while ((line = br.readLine()) != null) {
        // Split the line into individual parts, on the <tab> character
        String parts[] = line.split("\t");
        int sum = 0;
        // Staring from the first number, sum the line...
        for (int index = 1; index < parts.length; index++) {
            sum += Integer.parseInt(parts[index].trim());
        }
        // Store the key/value pairs together some how
    }
}

现在,我们需要一些方法来存储计算结果...

查看 Basic I/O 了解更多详情

管理数据

现在,有多种方法可以做到这一点,但由于数据量是可变的,因此您需要一个可以动态增长的数据结构。

我的第一个想法是使用 Map,但这假设你想合并具有相同名称的行,否则你应该只在 List 中使用 List ,其中外部 List 代表行, Inner 列表代表列值...

Map<String, Integer> data = new HashMap<>(25);
File[] files = listFiles(someDir, januraryFilter);
for (File file : files {
    readFile(file, data);
}

其中readFile基本上是之前的代码

protected void readData(File file, Map<String, Integer> data) throws IOException {
    try (BufferedReader br = new BufferedReader(new FileReader(file))) {
        String line = null;
        // Read each line
        while ((line = br.readLine()) != null) {
            //...
            // Store the key/value pairs together some how
            String name = parts[0];
            if (data.containsKey(name)) {
                int previous = data.get(name);
                sum += previous;
            }
            data.put(name, sum);
        }
    }
}

查看 Collections Trail 了解更多详情

正在显示数据

最后,我们需要展示数据。您可以简单地使用 DefaultTableModel,但您已经拥有结构中的数据,为什么不通过自定义 TableModel

重新使用它
public class SummaryTableModel extends AbstractTableModel {

    private Map<String, Integer> data;
    private List<String> keyMap;

    public SummaryTableModel(Map<String, Integer> data) {
        this.data = new HashMap<>(data);
        keyMap = new ArrayList<>(data.keySet());
    }
    
    @Override
    public int getRowCount() {
        return data.size();
    }

    @Override
    public int getColumnCount() {
        return 2;
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        Class type = Object.class;
        switch (columnIndex) {
            case 0:
                type = String.class;
                break;
            case 1:
                type = Integer.class;
                break;
        }
        return type;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Object value = null;
        switch (columnIndex) {
            case 0:
                value = keyMap.get(rowIndex);
                break;
            case 1:
                String key = keyMap.get(rowIndex);
                value = data.get(key);
                break;
        }
        return value;
    }
    
}

然后你只需将它应用到 JTable...

add(new JScrollPane(new JTable(new SummaryTableModel(data)));

查看 How to Use Tables 了解更多详情

结论

问题的上下文中缺少许多必须做出的假设;文件的顺序重要吗?您关心重复条目吗?

因此几乎不可能提供一个解决所有问题的“答案”