2015-06-04 32 views
-1

我仍然在學習JAVA和一直在試圖找到我的節目幾天一個解決方案,但我還沒有得到它尚未確定。JAVA讀取文本文件,統計的數字,寫它的JTable

我有很多的文本文件(我的程序保存)。該文件是這樣的:

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

(標籤),意味着有製表大關, 文本是指文本(字符串), 數字意味着有編號(整數)。

文件的數目可以是從1到32,並用類似的名稱文件:january1; january2; january3 ...

我需要閱讀所有這些文件(忽略字符串),總結只有數字,像這樣:

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; 

    } 

}; 

只要我想概括所有的「表」到數組的數組(或至任何類似的變量),然後將其顯示爲表格。如果有人知道任何解決方案或可以鏈接任何類似的計算,這將是太棒了!

+0

*「如果有人知道任何解決方案」 *編寫代碼。 *「..或者可以鏈接任何類似的計算..」* OT爲SO。 –

+1

解決問題。你需要閱讀文件。首先閱讀一個,查看[Basic I/O](http://docs.oracle.com/javase/tutorial/essential/io/)瞭解更多詳情。一旦你明白了這一點,你需要弄清楚如何列出滿足所需模式的文件,如['java.io.File'](https://docs.oracle.com/javase/7/docs /api/java/io/File.html)或[文件I/O(具有NIO.2)](https://docs.oracle.com/javase/tutorial/essential/io/fileio.html)可以做到。然後你需要決定如何管理數據,但是沒有足夠的上下文來回答這個問題,但是'List'的'Map'可以幫助 – MadProgrammer

+0

最後,你需要把所有的東西都放到'JTable'中,看看[如何使用表格](http://docs.oracle.com/javase/tutorial/uiswing/components/table.html)瞭解更多詳情。所以,真的,你問了四個問題...... – MadProgrammer

回答

1

所以,在我看來,你有你需要回答四個問題,這就違背了問一個問題的現場禮儀,但會給它一個鏡頭

  1. 如何列出了一系列文件的,大概使用某種過濾
  2. 如何以某種有意義的方式讀取文件和處理數據
  3. 如何管理數據結構中的數據
  4. 在0123顯示的數據。

清單文件

大概列出文件的最簡單的方法是使用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 s搜索多個不同的文件集。

當然,你也可以使用新的API Paths/Files查找文件以及

閱讀文件...

讀取多個文件歸結爲同樣的事情,讀一個單一的文件...

// 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代表行和Inner列表代表中我們List列值...

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更多細節

結論

有很多是必須作出的假設這是從問題的情況下丟失的;文件的順序是否重要?你關心重複的條目嗎?

使它成爲幾乎不可能提供一個單一的「答案」,這將解決所有你的問題

+0

我只是沒有提供我所有的代碼。這些都是很好的例子。是@MadProgrammer我希望所有文件中的每行都有相同的行。對我來說主要問題是讀取所有這些文件,並從商店寫入,導致存在空字段的問題,如果存在存儲的數據值變爲空,並且我無法將其寫入Jtable。那麼這些都是很好的例子,我希望它也能幫助其他人。 – Vilhis

1

我把所有從該位置january1 january2...文件,並使用相同的函數計算要存儲的值。

然後我創建了一個帶有兩個標題的表格DayNumber。然後根據生成的值添加行。

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); 
+0

*「試試這個:」* - 他們爲什麼要這樣做?你的方法對別人有什麼好處? – MadProgrammer

+0

我是第一個,「其他」從來沒有存在過。 –

+0

那麼?將會有其他人提供自己的答案,在OP上放置代碼塊沒有任何教育或提供他們學習識別好的或壞的例子所需的技能。 OP與他人之間沒有信任關係,爲什麼他們應該相信你和互聯網的其他人呢? – MadProgrammer

0

使用Labled Loop和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); 
+0

使用'Exception'作爲邏輯控制是一個糟糕的設計/模式 – MadProgrammer

+0

任何簡單的替代? – Rajesh

+0

真的沒有。從這個問題中,我們知道數據是以'String | Integer | ...'格式存在的,所以你可以簡單地跳過第一個元素,任何非數字的值都會觸發異常,因爲這就是它的原因 – MadProgrammer

0

下面是使用向量另一個例子。在這個例子中,目錄將被搜索「.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; 
    } 
} 
+2

從EDT的上下文開始你的用戶界面,並考慮使用'setSize'的['JFrame#pack'] – MadProgrammer

+0

請問....謝謝 –