3

列数とフィールド サイズが異なる固定幅ファイルのコレクションがあります。

ファイルの先頭は次のような行で始まります。

AAAAABBCCCCCCCCCCDDD など

文字の変化は、あるフィールドの終わりと別のフィールドの始まりを示します。これを使用して、コードでフィールド サイズを特定し、同じ値を以下の実際のデータ行に適用できると思います。

次に、読み取ったすべてのデータを XLS ファイルまたは DataGrid に出力したいのですが、これをコーディングする方法がわからないという問題があります。

どんな助けでも大歓迎です:)


/編集:

Cuong のソリューションを実装しました。自宅の PC でのテストでは問題なく動作しましたが、職場の PC には Windows XP が搭載されているため、c# v4 でコンパイルする必要がありました。

とにかく、入力ファイルを読み取ると、次のエラーが発生します。

************** Exception Text **************
System.ObjectDisposedException: Cannot read from a closed TextReader.
   at System.IO.__Error.ReaderClosed()
   at System.IO.StreamReader.ReadLine()
   at System.IO.File.<InternalReadLines>d__0.MoveNext()
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.IO.File.InternalWriteAllLines(TextWriter writer, IEnumerable`1 contents)
   at System.IO.File.WriteAllLines(String path, IEnumerable`1 contents)
   at FixedWidthFiles.Main.buttonProcessFile_Click(Object sender, EventArgs e)
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 (RTMRel.030319-0100)
    CodeBase: file:///C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
FixedWidthFiles
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/TEMP/FixedWidthFiles.exe
----------------------------------------
System.Windows.Forms
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 built by: RTMRel
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 built by: RTMRel
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 built by: RTMRel
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Core
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 built by: RTMRel
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------
4

3 に答える 3

1

TextReader.Readメソッドを使用できます。例えば:

    string input; // Test string

    // Replace new StringReader with a StreamReader to read a file
    using (TextReader textReader = new StringReader(input))
    {
        // Read first line to get structure
        var groupings = textReader.ReadLine().GroupBy(x => x);

        while (textReader.Peek() != -1)
        {
            // Convert to a string for easier handling than char[]
            List<string> fields = new List<string>();

            // Get the fields on each ling
            foreach (IGrouping<char, char> grouping in groupings)
            {
                char[] field = new char[grouping.Count()];
                textReader.Read(field, 0, field.Length);
                fields.Add(new string(field));
            }

            // Do something with "fields". The name of each field is
            // in grouping.Key at the same index.

            // Move to next line
            textReader.ReadLine();
        }
    }
于 2012-09-22T11:25:42.910 に答える
1

以下の例では、csv ファイル (Excel 形式) に書き込む方法を示しています。要点は、最初の行を読み取って幅を計算する必要があるということです。

var lines = File.ReadLines("C:\\input.txt");

var widthList = lines.First().GroupBy(c => c)
                             .Select(g => g.Count())
                             .ToList();

var list = new List<KeyValuePair<int, int>>();

int startIndex = 0;

for (int i = 0; i < widthList.Count(); i++)
{
    var pair = new KeyValuePair<int, int>(startIndex, widthList[i]);
    list.Add(pair);

    startIndex += widthList[i];
}

var csvLines = lines.Select(line => string.Join(",", 
                    list.Select(pair => line.Substring(pair.Key, pair.Value))));

File.WriteAllLines("C:\\test.csv", csvLines);
于 2012-09-23T08:21:37.117 に答える
1

Visual Basic のこのハウツーに従ってクラスTextFieldParserタイプを使用します。

フィールドの幅を指定する必要があります。最初の行があれば、それは簡単です。

于 2012-09-22T11:14:55.783 に答える