假设我有个文本文件,有如下基本格式(像Table一样的),+----------+----------+
|  data0   |   data1  |
|----------|----------|
|  data3   |   data4  |
+----------+----------+如果我要只读取data的内容,而忽略"+", "-", "|"等特殊格式字符,然后,把data按列保存在相应数组中(第一列column1[0],第二列column2[1]...),请问我应该如何写这个读取文件的程序呢?

解决方案 »

  1.   

    我感觉你应该抛开文本文件这个误区。完全看做是字符串
    "|  data0  |  data1  | 
     |  data3  |  data4  |".
      

  2.   


    嗯?这个怎么解释呢?那我应该如何选择我需要的数据呢,也就是找例子中的data
      

  3.   

    public static void main(String[] args) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader("c:\\1.txt"));
    String line = reader.readLine();
    List<String> column1 = new ArrayList<String>();
    List<String> column2 = new ArrayList<String>();
    //....
    while(line != null) {
    if (line.charAt(0)!='+') {
    String[] values = line.split("\\|");
    column1.add(values[1].trim());
    column2.add(values[2].trim());
    //...
    }
    line = reader.readLine();
    }
    }
      

  4.   

    4楼的思路已经很准确了,但是还存在点瑕疵,那就是“--------”。也会被作为元素存在list中。我将其稍作完善。在eclipse下可以运行的代码(jkd1.5以上)package com.fc.bayern;import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;public class TreatCharacter { public static void main(String[] args) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader("c:\\1.txt"));
    String line = reader.readLine();
    List<String> column1 = new ArrayList<String>();
    List<String> column2 = new ArrayList<String>();
    // ....
    while (line != null) {
    if ((line.charAt(0) != '+')
    && !((line.charAt(0) == '|') && line.charAt(1) == '-')) {
    String[] values = line.split("\\|");
    column1.add(values[1].trim());
    column2.add(values[2].trim()); } line = reader.readLine();
    }
    for (int i = 0; i < column1.size(); i++) {
    System.out.println(column1.get(i));
    }
    System.out.println("******************");
    for (int j = 0; j < column2.size(); j++) {
    System.out.println(column2.get(j));
    }
    }}
      

  5.   

    请教楼上2位,用List和ArrayList的而不用普通数组的根据是什么呢?我原本一点也没考虑到要用ArrayList,所以这里也想再顺便问下,什么时候什么条件下应该采用的诸如ArrayList等实用类呢?
      

  6.   

    哦,关于下面这句判断我没看明白,为什么会在charAt(0)判断2次呢?if ((line.charAt(0) != '+')&& !((line.charAt(0) == '|') && line.charAt(1) == '-'))还有下面这段也是,为什么values[]是从index=1开始,不是0?难道values[0]的值是‘|’吗?String[] values = line.split("\\|");
    column1.add(values[1].trim());
    column2.add(values[2].trim());
    对于上面的疑问能否再详细解释一下呢?在此先深表感谢了。另外,在上面这个例子中是不是可以使用StringTokenizer这个实用类呢,或者Scanner这个,貌似这2个都是可以处理String。
      

  7.   

    采用集合框架来处理比较方便。之所以判断两次是因为|----------|----------| 这种行是你所不需要的。要扣除它。之所以是从value[1]开始而不从value[0]开始是因为vlaue[0]装的是'|'StringTokenizer是目前并不推荐采用的方法,因为目前公认的处理字符串的利器应该是正则表达式(regular expression).关于这个程序你只要在eclipse中debug一下就一目了然了。
      

  8.   


    package com.regExp;import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.InputStreamReader;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;public class Tester { /**
     * @param args
     */
    public static void main(String[] args) throws Exception{
    // TODO Auto-generated method stub
    String[][] str=new String[100][100];//初始为100*100
    BufferedReader br = new BufferedReader(new InputStreamReader(
    new FileInputStream("D:\\MyEclipse 7.0\\j2se\\Utils\\src\\table.txt")));
    String s="";
    String regexp="\\w+";
    int rows=0;
    while((s=br.readLine())!=null){
    Pattern pattern=Pattern.compile(regexp);
    Matcher matcher=pattern.matcher(s);
    int cols=0;
    while(matcher.find()){
    str[rows][cols++]=matcher.group();
    }
    rows++;
    }
    for(int i=0;i<str.length;i++){
    for(int j=0;j<str[i].length;j++){
    if(str[i][j]!=null){
    System.out.print(str[i][j]+"  ");
    }
    }
    System.out.println();
    }
    }
    }
    测试通过
      

  9.   

    不过,貌似在读取中好像还有写小问题,假设我原来那个的文本文件的格式进行了扩展,更新为如下:+---------------+--------+----------------+-------+---------+----------------+------------+--------------+
    | name          | passwd | st_addr        | state | country | st_addr_bill   | state_bill | country_bill |
    +---------------+--------+----------------+-------+---------+----------------+------------+--------------+
    | CustomerName0 | 0      | CustomerAddrs0 | NY    | USA     | CustomerAddrs0 | NY         | USA          | 
    | CustomerName1 | 1      | CustomerAddrs1 | MI    | USA     | CustomerAddrs1 | MI         | USA          | 
    | CustomerName2 | 2      | CustomerAddrs2 | TX    | USA     | CustomerAddrs2 | TX         | USA          | 
    +---------------+--------+----------------+-------+---------+----------------+------------+--------------+然后保存为LoadCustomer.dat文件,我根据楼上各位好友的思路也写了下code,具体如下:
    import java.io.*;
    import java.util.*;public class readDATFile { /**
     * @param args
     */
    public static void main(String[] args) throws IOException {
    BufferedReader inputStream = null;
            PrintWriter outputStream = null;
            //Scanner s = null;
            //StringTokenizer strtok = null;        try {
                inputStream =
                    new BufferedReader(new FileReader("LoadCustomer.dat"));            String l="";
                for(int i=0; i<3; i++)  // 为了跳过前3行,使l从第4行开始
                 l = inputStream.readLine();            List<String> name = new ArrayList<String>();
                List<String> password = new ArrayList<String>();
                
                while ((l = inputStream.readLine()) != null) {
                 if(!(l.charAt(1) == '|')){
                 String[] values = l.split("\\|");
                 name.add(values[1].trim());
                 password.add(values[2].trim());
                 }
                 l = inputStream.readLine();            }
                for (int i = 0; i < name.size(); i++) { //输出第1列数据
                    System.out.println(name.get(i));
                }
                for (int i = 0; i < password.size(); i++) {  //输出第2列数据
                    System.out.println(password.get(i));
                }        } finally {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            }
        }
    }
    不过上面代码执行的结果有些奇怪,第1列里为何只有CustomerName0和CustomerName2的数据,第2列里也只有0和2,也就是把中间一行给跳掉了,不知能否再分析一下原因呢?
      

  10.   

    嗯,头疼,搞了许久还不对,可能我还是对split()方法不理解吧,还有那个正则表达式,期待高手的回复了
      

  11.   

    唉,自己终于写出来了,其实原来已经很接近的了,关键还是if那里没弄清楚import java.io.*;
    import java.util.*;public class readDATFile { /**
     * @param args
     */
    public static void main(String[] args) throws IOException { BufferedReader inputStream = null;
            PrintWriter outputStream = null;        try {
                inputStream =
                    new BufferedReader(new FileReader("LoadCustomer.dat"));            String l="";
                for(int i=0; i<3; i++)
                 l = inputStream.readLine();            List<String> name = new ArrayList<String>();
                List<String> password = new ArrayList<String>();
                String[] values;            while ((l = inputStream.readLine()) != null) {             if((l.charAt(0) == '|') && l.charAt(1) == ' '){
                 values = l.split("[|]");
                 name.add(values[1].trim());
                 password.add(values[2].trim());             }            }
                for (int i = 0; i < name.size(); i++) {
                    System.out.println(name.get(i));
                }
                for (int i = 0; i < password.size(); i++) {
                    System.out.println(password.get(i));
                }        } finally {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } }}结果:
    CustomerName0
    CustomerName1
    CustomerName2
    0
    1
    2
    这样就正确了 =)
      

  12.   

    现在又有一个奇怪的问题了,用上面同样的方法读取如下的内容,会报 java.lang.StringIndexOutOfBoundsException: String index out of range: 0 的错误...+----------+---------+--------+-------+-------+---------+-----------+----------+-------+-------+
    | catalogn | medium  | colour | fstop | speed | size    | available | image    | price | name  |
    +----------+---------+--------+-------+-------+---------+-----------+----------+-------+-------+
    |        1 | Film    | B      |    16 | 1/4   | 300x300 | Y         | A001.png |  1341 | A Sti |
    |        2 | Film    | B      |     6 | 1/30  | 600x600 | Y         | A002.png |   433 | A Sti |
    |        6 | Digital | B      |    11 | 1/4   | 300x300 | Y         | B001.png |   400 | A Ker |
    |       16 | Video   | B      |     8 | 1/250 | 600x600 | Y         | R050.png |   340 | A New |
    |       26 | Digital | B      |    11 | 1/4   | 75x75   | Y         | Z000.png |   320 | M Whi |
    |       27 | Digital | B      |    16 | 1/2   | 300x300 | Y         | Z002.png |   800 | M Whi |
    +----------+---------+--------+-------+-------+---------+-----------+----------+-------+-------+就这个表不行,其他的表用上面的方法都可以的,真搞不懂了呵,希望大家能帮忙看下,debug一下,多谢了
      

  13.   

    呵呵,楼主的问题越来越复杂啊
    正巧,我们项目组也正在做一个文件导入清洗的模块,这些东西都已经实现了,甚至比access做的还好,不过,比较复杂。
      

  14.   

    如果你就想解析下面这格式, 用4楼的改进下就可以了. 至于你说的 java.lang.StringIndexOutOfBoundsException多半是对空行用了trim()后再用charAt(0)造成的, 下面我写了个例子供参考, column1[0] 就表示第一列, column1[o].get(0) 表示第一列第一个
    +----------+---------+--------+-------+-------+---------+-----------+----------+-------+-------+ 
    | catalogn | medium  | colour | fstop | speed | size    | available | image    | price | name  | 
    +----------+---------+--------+-------+-------+---------+-----------+----------+-------+-------+ 
    |        1 | Film    | B      |    16 | 1/4  | 300x300 | Y        | A001.png |  1341 | A Sti | 
    |        2 | Film    | B      |    6 | 1/30  | 600x600 | Y        | A002.png |  433 | A Sti | 
    |        6 | Digital | B      |    11 | 1/4  | 300x300 | Y        | B001.png |  400 | A Ker | 
    |      16 | Video  | B      |    8 | 1/250 | 600x600 | Y        | R050.png |  340 | A New | 
    |      26 | Digital | B      |    11 | 1/4  | 75x75  | Y        | Z000.png |  320 | M Whi | 
    |      27 | Digital | B      |    16 | 1/2  | 300x300 | Y        | Z002.png |  800 | M Whi | 
    +----------+---------+--------+-------+-------+---------+-----------+----------+-------+-------+ public static void print() throws IOException{
            BufferedReader reader = new BufferedReader(new FileReader("f:\\1.txt"));
            String line = reader.readLine();
            List[] column1 = new ArrayList[0];
            
            while (line != null){  //creates columns
             line = line.trim();
             if (line.length() > 0 && line.charAt(0) == '+'){
             String[] values = line.split("\\+");
             column1 = new ArrayList[values.length - 1];
             for (int i = 0; i < column1.length; i++){
             column1[i] = new ArrayList();
             }
             line = reader.readLine();
             break;
             }
             line = reader.readLine();
            }        while(line != null) {
             line = line.trim();
                if (line.length() > 0 && line.charAt(0) != '+') {
                    String[] values = line.split("\\|");
                    for (int i = 0, j = 1; j < values.length; i++, j++)
                        column1[i].add(values[j].trim());
                }
                line = reader.readLine();
            }
            
            reader.close();        for (int i = 0; i < column1.length; i++){
             System.out.println(column1[i]);
            }
    }
      

  15.   

    用正则表达式和readLine就简单解决了!!!!!!
      

  16.   

    嗯,没错,因为trim的关系,所以在charAt(0)thorw OutOfBoundsException,我只要在我原来写的if条件里再加下l.length()>0就对了,唉,还是自己不是很仔细呵...还是要非常感谢你的提醒呵,当然还有其它各位的帮助,thanks