本帖最后由 gidiyis 于 2010-02-02 23:37:52 编辑

解决方案 »

  1.   

    楼主的实际问题一定不会是这几行数据了.可以把这两类数据建成三个数据表
    表1: 试样信息   aa|10|1|良好商品| ...
    表2: 产品信息   abc|10|测试1|2|备注| ...
    表3: 产品统计   id,name,count,res,goodproductNo,badproductNo用数据库解决统计问题就很容易了。
      

  2.   


                string[] temp = System.IO.File.ReadAllLines("E:\\aaa.txt", System.Text.Encoding.GetEncoding("gb2312"));
                Dictionary<int, product> dic = new Dictionary<int, product>();
                foreach (string s in temp)
                {
                    if (s.StartsWith("abc"))
                    {
                        string[] pInfo = s.Split('|');
                        int id = int.Parse(pInfo[1]);
                        if (!dic.ContainsKey(id))
                        {
                            product p = new product();
                            p.id = id;
                            p.name = pInfo[2];
                            p.count = int.Parse(pInfo[3]);
                            p.res = pInfo[4];
                            dic.Add(id, p);
                        }
                    }
                    else if (s.StartsWith("aa"))
                    {
                        string[] qInfo = s.Split('|');
                        int id = int.Parse(qInfo[1]);
                        if (dic.ContainsKey(id))
                        {
                            product p = dic[id];
                            int count = int.Parse(qInfo[2]);
                            string quality = qInfo[3];
                            if (quality == "良好商品")
                                p.goodproductNo += count;
                            else if (quality == "不良商品")
                                p.badproductNo += count;
                        }
                    }
                }
                foreach (int i in dic.Keys)
                {
                    product p = dic[i];
                    Console.WriteLine("Id:{0},name:{1},count:{2},res:{3},goodproductNo:{4},badproductNo:{5}", p.id, p.name, p.count, p.res, p.goodproductNo, p.badproductNo);
                }
    /*
    输出:
    Id:10,name:测试1,count:2,res:备注,goodproductNo:2,badproductNo:0
    Id:11,name:测试2,count:3,res:备注,goodproductNo:2,badproductNo:1*/
      

  3.   

    支持读到datatable里,然后再操作
      

  4.   

    3楼的程序设计是对的,可以满足楼主的需求,csdn高手还是很多啊,欣喜................
      

  5.   

    读到DataTable中,然后循环呗判断呗或者先直接把每行都new一个pruduct实例,这样你就可以得到一个List<Product>的集合,然后用linq来写判断条件跟方便了
      

  6.   

    用OLEDB 连接TXT文件 用sql语句 查询
    载入文件前创建txt分割相关的配置文件
      

  7.   

    abc表示该行描述的是一个产品,10/11代表产品编号,2表示产品数量 
    aa表示该行是对产品的描述信息(产品良好或不良),10/11来自abc编号,1表示产品数量最好把这两个能分成两个文件存储。
      

  8.   

    这才是正解...虽然效率也一般,但在数据源不能改变时这个才能叫解决方案...用ReadAllLines这个txt文件很大怎么办?数据源改变时怎么办?重ReadAllLines?
      

  9.   

            static void Main(string[] args)
            {
                string FilePath = @"C:\Users\chenjun\Desktop";            INIClass iniMake = new INIClass(@"C:\Users\chenjun\Desktop\Schema.ini");            iniMake.IniWriteValue("11.txt", "Format", "Delimited(|)");
                iniMake.IniWriteValue("11.txt", "ColNameHeader", "false");
                iniMake.IniWriteValue("11.txt", "col1", "RowType TEXT WIDTH 100 ");
                iniMake.IniWriteValue("11.txt", "col2", "ProductID TEXT WIDTH 100 ");
                iniMake.IniWriteValue("11.txt", "col3", "Colmn1 TEXT WIDTH 100");
                iniMake.IniWriteValue("11.txt", "col4", "Colmn2 TEXT WIDTH 100 ");
                iniMake.IniWriteValue("11.txt", "col5", "Colmn3 TEXT WIDTH 100 ");
                string constr = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + FilePath + "';Extended Properties='text;HDR=No;FMT=Delimited(|);'";
                OleDbDataAdapter da = new OleDbDataAdapter();
                OleDbConnection OConn = new OleDbConnection();
                OConn.ConnectionString = constr;
                OConn.Open();
                OleDbCommand OCmm = new OleDbCommand();
                OCmm.Connection = OConn;
                da.SelectCommand = OCmm;
                OCmm.CommandTimeout = 0;
                DataTable ProtuctTable = new DataTable();
                DataTable QualityTable = new DataTable();
                OCmm.CommandText = "Select ProductID,Colmn1 as ProductName,Colmn2 as ProductCount,Colmn3 as ProductComment from [11.txt] where RowType='abc'";
                da.Fill(ProtuctTable);
                OCmm.CommandText = "Select ProductID,Sum(Colmn1) as Amount,Colmn2 as ProductMass from [11.txt] where RowType='aa' Group By ProductID,Colmn2";
                da.Fill(QualityTable);
                da.Dispose();
                OCmm.Dispose();
                OConn.Dispose();
                foreach (DataRow dr in ProtuctTable.Rows)
                {
                    DataRow[] rows = QualityTable.Select("ProductID=" + dr["ProductID"]);
                    foreach (DataRow row in rows)
                    {
                        Console.WriteLine(dr["ProductID"] + " " + dr["ProductName"] + " " + row["ProductMass"] + " " + row["Amount"]);
                    }
                }
                Console.ReadLine();
            }
      

  10.   

    INIClass     /// <summary>
        /// ini文件操作
        /// </summary>
        public class INIClass
        {
            public string inipath;
            [DllImport("kernel32")]
            private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
            [DllImport("kernel32")]
            private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);
            /// <summary>
            /// 构造方法
            /// </summary>
            /// <param name="INIPath">文件路径</param>
            public INIClass(string INIPath)
            {
                inipath = INIPath;
            }
            /// <summary>
            /// 写入INI文件
            /// </summary>
            /// <param name="Section">项目名称(如[TypeName] )</param>
            /// <param name="Key">键</param>
            /// <param name="Value">值</param>
            public void IniWriteValue(string Section, string Key, string Value)
            {
                WritePrivateProfileString(Section, Key, Value, this.inipath);
            }
            /// <summary>
            /// 读出INI文件
            /// </summary>
            /// <param name="Section">项目名称(如[TypeName] )</param>
            /// <param name="Key">键</param>
            public string IniReadValue(string Section, string Key)
            {
                StringBuilder temp = new StringBuilder(500);
                int i = GetPrivateProfileString(Section, Key, "", temp, 500, this.inipath);
                return temp.ToString();
            }
        }
      

  11.   

    对txt硬搞不是好办法吧,最好以这个txt为数据库来操作用txt做数据源连接字符串//text作为数据源的链接字符串
                string strConnection = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\\test;
    Extended Properties=""text;HDR=Yes;FMT=Delimited"";";注意:c:\\test是个文件夹,里面有相应的txt文档做数据源。
      

  12.   

    http://blog.csdn.net/LCL_data/archive/2009/12/18/5032160.aspx
      

  13.   

    ojlovecd (三楼)确实是高人啊,谢谢你的解答,我的问题解决了
      

  14.   

    闲来无事,参照3楼的改写成逐行分析的,这样在文件较大时候也不会出问题了,呵呵 有剽窃嫌疑……using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;namespace ParseTXT
    {
        class Program
        {
            static void Main(string[] args)
            {
                string TxtFilePath = "Product.txt";
                Dictionary<int, Product> productDic = new Dictionary<int, Product>();
                using (StreamReader TxtSR = new StreamReader(TxtFilePath, Encoding.GetEncoding("gb2312")))
                {                
                    String temp = TxtSR.ReadLine();
                    while (!string.IsNullOrEmpty(temp))
                    {                    Console.WriteLine(temp);
                        string[] tempProduct = temp.Split('|');
                        if (tempProduct[0] == "abc")
                        {
                            int productID = Int32.Parse(tempProduct[1]);
                            if (!productDic.ContainsKey(productID))
                            {
                                Product pro = new Product();
                                pro.id = Int32.Parse(tempProduct[1]);
                                pro.name = tempProduct[2];
                                pro.count = Int32.Parse(tempProduct[3]);
                                productDic.Add(productID, pro);
                            }
                        }
                        if (tempProduct[0] == "aa")
                        {
                            int productID = Int32.Parse(tempProduct[1]);
                            if (tempProduct[3] == "良好商品")
                            {
                                productDic[productID].goodproductNo += Int32.Parse(tempProduct[2]);
                            }
                            if (tempProduct[3] == "不良商品")
                            {
                                productDic[productID].badproductNo += Int32.Parse(tempProduct[2]);
                            }                    }                    temp = TxtSR.ReadLine();
                    }
                }
                //TxtSR.Close();
                foreach (int productID in productDic.Keys)
                {
                    Console.WriteLine(
                        "Product Name: {0}, "+
                        "Product Count: {1}, "+
                        "Product Good Number: {2}, "+
                        "Product Bad Number: {3}", productDic[productID].name, productDic[productID].count, productDic[productID].goodproductNo, productDic[productID].badproductNo);
                }
            }
        }    class Product
        {
            public Product()
            {
                //
            }
            public int id;
            public string name;
            public int count;//(数量)
            public bool res;
            public int goodproductNo; //(良品数量)
            public int badproductNo;//(次品数量)
        }
    }
      

  15.   


            /// <summary>
            /// 读入一个pds导出的管线文件,通过参数返回
            /// </summary>
            /// <param name="FilePath">文件路径</param>
            /// <param name="data">数据</param>
            /// <param name="columns">列表栏位</param>
            /// <param name="Msg">消息,成功读取时为空,由于考虑需要一次对整个文件进行检验,所以没有直接抛出异常,而使用msg返回</param>
            /// <returns>bool</returns>
            public bool PipingFileReader(string FilePath, out List<Dictionary<string, string>> data, out List<string> columns, out string Msg)
            {
                string strLine;
                string strHeader;
                string strDataArea;
                string[] strArray;
                char[] charArray = new char[] {'|'};
                int RowCnt = 0;
                int cntHeaderColumns;
                int cntDataAreaCloums;
                int cntDataAreaRows = 0;
                //初始返回
                data = new List<Dictionary<string, string>>();
                columns = new List<string>();
                Msg = "";            try
                {
                    FileStream aFile = new FileStream(FilePath, FileMode.Open);
                    StreamReader sr = new StreamReader(aFile,Encoding.Default);//使用默认编码,防止乱码                // Obtain the columns from the first line                // Split row of data into string array
                    strLine = sr.ReadLine();
                    RowCnt++;
                    //顺序读取直到表头区域
                    while (strLine != null)
                    {
                        if (IsHeaderRow(strLine))
                        {
                            break;
                        }
                        strLine = sr.ReadLine();
                        RowCnt++;
                    }
                    //对数据表头进行检查
                    if (CheckTableHeader(strLine))
                    {
                        strHeader = TrimHeaderRow(strLine);
                        strArray = strHeader.Split(charArray);
                        cntHeaderColumns = strArray.GetUpperBound(0);//GetUpperBound(0) 返回 Array 的第一维的索引上限,GetUpperBound(Rank - 1) 返回 Array 的最后一维的上限。此方法的运算复杂度为 O(1)。
                        columns.Add("行号");//记录该行数据在源文件中的行号
                        for (int x = 0; x <= cntHeaderColumns; x++)
                        {
                            columns.Add(strArray[x].Trim());
                        }
                    }
                    else
                    {
                        Msg = "错误的单线材料表表头\r\n";
                        return false;
                    }
                    strLine = sr.ReadLine();
                    RowCnt++;
                    while (strLine != null)
                    {
                        if (IsDataRow(strLine))
                        {//如果遇到数据行
                            // Split row of data into string array
                            strDataArea = TrimDataRow(strLine);
                            strArray = strDataArea.Split(charArray);
                            Dictionary<string, string> dataRow = new Dictionary<string, string>();
                            cntDataAreaCloums=strArray.GetUpperBound(0);
                            if (cntDataAreaCloums != cntHeaderColumns)
                            {
                                Msg += "第" + RowCnt + "数据格式错误\r\n";
                            }
                            else
                            {
                                dataRow.Add("行号", RowCnt.ToString());//记录该行数据在源文件中的行号
                                for (int x = 0; x <= cntDataAreaCloums; x++)
                                {                       //将索引该为1,0号位已经改为“行号”
                                    dataRow.Add(columns[x + 1], strArray[x].Trim());
                                                                      //但是此索引任然应该从0开始
                                }
                                data.Add(dataRow);
                                cntDataAreaRows++;
                            }
                        }
                        strLine = sr.ReadLine();
                        RowCnt++;
                    }                sr.Close();
                    if (Msg == "")
                    {
                        if (cntDataAreaRows % 2 == 0)
                        {
                            return true;
                        }
                        else
                        {
                            Msg = "数据区异常:没有保存数据区的2行缺省\r\n";
                            return false;
                        }
                    }
                    else
                    {
                        return false;
                    }
                }
                catch (IOException ex)
                {
                    Msg += ex.ToString();
                    return false;
                }
            }        /// <summary>
            /// 对单线转换为datatable的预处理
            /// </summary>
            /// <param name="Path">文件路径</param>
            /// <param name="Msg">错误消息</param>
            /// <returns></returns>
            public DataTable PrePipingTable(string Path, out string Msg)
            {
                List<Dictionary<string, string>> data;
                List<string> columns;
                DataTable dt = new DataTable();
                bool IsSuccess = PipingFileReader(Path, out data, out columns,out Msg);
                if (!IsSuccess)
                {
                    return dt;
                }            foreach (string column in columns)
                {
                    dt.Columns.Add(column,System.Type.GetType("System.String"));
                }            foreach (Dictionary<string, string> row in data)
                {
                    DataRow dr = dt.NewRow();
                    foreach (string clolumn in columns)
                    {
                        dr[clolumn] = row[clolumn];
                    }
                    dt.Rows.Add(dr);
                }
                return dt;
            }给你个参考,这个是我写的读pds单线材料表的类,格式和你这个差不多,只是有验证,所以你稍微删除修改下就可以把你那个文件读到datatable了,想做什么都统计都好办了。可以通用的。