程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 對文本文件中的記錄進行排序的小工具

對文本文件中的記錄進行排序的小工具

編輯:關於.NET

前幾天為工作中的一個實際問題編寫了一個小工具,但應該說“麻雀雖小, 五髒俱全”,同樣涉及到了設計、編碼、測試幾個過程,並且其中涉及到一些有 趣的知識,拿出來和大家分享一下。

首先來說明一下想要解決的問題:

當前每個月公司中的某個部門都會在特定的一天(一般是月初)下載大量的 數據,這些數據是從數據庫中取得的,生成文本格式的文件,然後用來做後續的 處理,類似於EDI的程序。但是,後續處理的程序需要所有的記錄都是經過排序 的,而現在的下載數據的程序是這樣做的,直接寫帶有Order by的SQL語句,然 後直接生成數據。但是這樣的話,程序運行的時間非常長,因為在服務器中的內 存中進行排序,會耗費大量的資源。這還不是主要問題,主要的問題在於下載數 據的時候會對其他部門進行系統操作造成極大的影響,甚至於會造成系統的停頓 和沒有響應。

因此我考慮在下載數據的時候不對數據進行排序,而是把排序工作拿出來, 用一個專門的小程序來實現,這樣就可以即使會造成性能下降也只局限在運行小 工具程序的那台機器,而不會對公司其他用戶造成影響。(後來發現對本機的性 能也沒有太大的影響)。

遵循這個思路,我所需要做的就是開發一個專門用來對這些數據排序的小工 具。為了提高工作的效率,我是用VS 2005來開發,盡管公司中大多數項目使用 的都是Java,呵呵。

首先是如何對文本文件中的數據進行排序,其實很簡單,我只是將這個文本 文件作為數據源,配置在ODBC中了。

然後呢,在VS 2005的服務器管理器中就可以配置對這個數據源的訪問。

但是,此時會有兩個問題:

一是對身份證號碼這樣的字段,系統會默認為是浮點數,這樣查詢出來看到 的記過是科學計數法的形式,而實際上我想要的是文本的類型。

這個問題可以使用配置數據源的Schema來解決,

裡面可以將每個字段都指定為文本類型,這樣就方便導出了。

但是隨之而來的就會有第二個問題,那就是這個文件必須指定文件名,而每 次需要排序的文件名都是不一樣的。

對這個問題,我是這樣解決的,先將需要排序的文件copy到這個臨時目錄中 ,並指定固定的文件名,然後在這個目錄中針對固定的文件名進行字段類型的配 置就可以了。針對這個文件排序之後,生成一個排序好的文本文件,然後再把這 個文件復制到指定的目標文件中。

這樣基本上技術問題就都解決掉了。最後是對界面的一個設計,先看一下界 面:

這裡我設置了一個小技巧,當用戶選擇了源文件之後,我會自動根據這個名 字,在後面加上_Sorted,作為輸出的文件名,這樣就方便用戶了。

最後,下面是以下關鍵的代碼:

//將選擇的文件名稱顯示在源文件的輸入框中
       OpenFileDialog openSourceFile = new  OpenFileDialog();
       initializeFileOpenDialog(openSourceFile);
       if (openSourceFile.ShowDialog() == DialogResult.OK)
       {
         String fileName = openSourceFile.FileName;
         txtSourceFile.Text = fileName;
         //如果文件名不為空,則自動生成目標文件的名稱
         if (!fileName.Trim().Equals(String.Empty))
         {
           int extendNamePosition = fileName.IndexOf (".");
           String targetFileName = fileName.Substring (0, extendNamePosition) + "_Sorted" + "." + fileName.Substring (extendNamePosition + 1);
           txtTargetFile.Text = targetFileName;
         }
       }

這是排序的操作以及相應的文件操作,其中使用了微軟的Enterprise Library 3.1的DataAccess類庫。而且讀出來的數據直接放在IDataReader中處理 ,比使用DataSet會快不少。

private void btnSort_Click(object sender, EventArgs e)
     {
       if (txtSourceFile.Text.Trim().Equals(String.Empty))
       {
         MessageBox.Show("請先選擇源文件。");
         return;
       }
       if (txtTargetFile.Text.Trim().Equals(String.Empty))
       {
         MessageBox.Show("請先指定目標文件名。");
         return;
       }
       //先將源數據復制到指定的文件夾中
       //然後以該文件夾中的數據作為數據源進行操作
       CurrentJobInfo.Text = "正在將文件復制到臨時文件夾中… …";
       CopyFileToTempPath();
       //對臨時文件夾中的數據進行排序
       CurrentJobInfo.Text = "正在排序……";
       Database db = DatabaseFactory.CreateDatabase ("DataStore");
       String strSql = CreateSql();
       DbCommand dbCommand = db.GetSqlStringCommand (strSql);
       //准備輸出的文件
       String sortedFileName = getSortedFileName();
       FileInfo sortedFile = new FileInfo(TEMP_DATA_PATH  + sortedFileName);
       StreamWriter writer = sortedFile.CreateText();
       //將數據寫入到文件中
       using (IDataReader dr = db.ExecuteReader (dbCommand))
       {
         while (dr.Read())
         {
           StringBuilder sbRecord = new StringBuilder ();
           for (int i = 0; i < dr.FieldCount -  1; i++)
           {
             sbRecord.Append(dr[i].ToString() +  ",");
           }
           sbRecord.Append(dr[dr.FieldCount -  1].ToString());
           writer.WriteLine(sbRecord.ToString());
         }
       }
       writer.Close();
       //將排序好的文件輸出到目標文件中
       File.Delete(txtTargetFile.Text);
       File.Copy(TEMP_DATA_PATH + sortedFileName,  txtTargetFile.Text);
       CurrentJobInfo.Text = "完成!";
     }

希望對這個問題的解決思路能夠對大家解決類似的問題有些幫助,也希望大 家一起來討論,:)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved