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、Day
和 Number
创建了一个 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 问题的网站礼仪,但会试一试
- 如何列出一系列文件,大概使用某种过滤器
- 如何以某种有意义的方式读取文件和处理数据
- 如何管理数据结构中的数据
- 在
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 了解更多详情
结论
问题的上下文中缺少许多必须做出的假设;文件的顺序重要吗?您关心重复条目吗?
因此几乎不可能提供一个解决所有问题的“答案”
我还在学习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、Day
和 Number
创建了一个 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 问题的网站礼仪,但会试一试
- 如何列出一系列文件,大概使用某种过滤器
- 如何以某种有意义的方式读取文件和处理数据
- 如何管理数据结构中的数据
- 在
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 了解更多详情
结论
问题的上下文中缺少许多必须做出的假设;文件的顺序重要吗?您关心重复条目吗?
因此几乎不可能提供一个解决所有问题的“答案”