2008-10-02 55 views
17

我有一個文本文件,其中每個記錄中的每個字段都是固定寬度的記錄。我的第一種方法是簡單地使用string.Substring()來解析每條記錄。有沒有更好的辦法?從文本文件中讀取固定寬度記錄

例如,該格式可以被描述爲:

<Field1(8)><Field2(16)><Field3(12)> 

而且有兩個記錄的示例文件可能看起來像:

SomeData000000000SomeMoreData 
Data2 0000000000555555MoreData  

我只是想確保我不要忽略比Substring()更優雅的方式。


更新:我最終與像Killersponge正則表達式去建議:

private readonly Regex reLot = new Regex(REGEX_LOT, RegexOptions.Compiled); 
const string REGEX_LOT = "^(?<Field1>.{6})" + 
         "(?<Field2>.{16})" + 
         "(?<Field3>.{12})"; 

我然後使用以下方法來訪問字段:

Match match = reLot.Match(record); 
string field1 = match.Groups["Field1"].Value; 

回答

5

子串聽起來不錯。我可以立即想到的唯一缺點是它意味着每次都要複製數據,但我不會擔心,直到你證明它是一個瓶頸。子串是簡單的:)

可能使用一個正則表達式來匹配整個記錄,並捕獲字段,但我認爲這將是矯枉過正。

+0

是的,我試圖想到一種使用正則表達式的方式,但認爲這是工作的錯誤工具,正如你所說的,矯枉過正。 – 2008-10-02 14:59:24

+0

正則表達式? ^(。{8})(。{16})(。*)$作爲字段的上述定義,假設最後一個字段可能用或不用空格填充。 – Sekhat 2008-10-02 15:01:51

1

不,子串是罰款。這就是它的目的。

2

如果行尾沒有填充空格來填充字段,那麼您可能不得不注意,如果沒有一點小竅門來確定該行的多少行,那麼您的子字符串將不起作用是閱讀。這當然只適用於最後一個字段:)

21

使用FileHelpers

例子:

[FixedLengthRecord()] 
public class MyData 
{ 
    [FieldFixedLength(8)] 
    public string someData; 

    [FieldFixedLength(16)] 
    public int SomeNumber; 

    [FieldFixedLength(12)] 
    [FieldTrim(TrimMode.Right)] 
    public string someMoreData; 
} 

然後,它是如此簡單:

var engine = new FileHelperEngine<MyData>(); 

// To Read Use: 
var res = engine.ReadFile("FileIn.txt"); 

// To Write Use: 
engine.WriteFile("FileOut.txt", res); 
1

您可以爲固定格式文件設置ODBC數據源,然後像訪問其他數據庫表一樣訪問它。 這有一個額外的好處,即文件格式的特定知識不會編譯到您的代碼中,以致有人決定在中間粘貼額外的字段。

相關問題