1

ここにCuongのソリューションを実装しました: C#固定幅ファイルの処理

これが私のコードです:

        var lines = File.ReadAllLines(@fileFull);
        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(filePath + "\\" + fileName + ".csv", csvLines);

@fileFull=ファイルのパスと名前

私が抱えている問題は、入力ファイルの最初の行にも数字が含まれていることです。したがって、AAAAAABBCB111111111DD2EEEEEEなどである可能性があります。何らかの理由で、Cuongのコードからの出力により、1111RRRRや222223333などのCSV見出しが表示されます。

なぜこれがなぜであり、私がそれをどのように修正するのか誰かが知っていますか?


ヘッダー行の例:

AAAAAAAAAAAAAAAABBBBBBBBBBCCCCCCCCDEFCCCCCCCCCGGGGGGGGHHHHHHHHIJJJJJJJJKKKKLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOPPPPQQQQ1111RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR222222222333333333444444444555555555666666666777777777888888888999999999S00001111TTTTTTTTTTTTUVWXYZ!"£$$$$$$%&  

変換されたヘッダー行:

AAAAAAAAAAAAAAAA    BBBBBBBBBB  CCCCCCCCDEFCCCCCC   C   C   C   GGGGGGGG    HHHHHHHH    I   JJJJJJJJ    KKKK    LLLL    MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM  NNNNNNNNNNNNNNNNNNNNNNNNNNNNNN  OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO  PPPP    QQQQ    1111RRRR    RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR2222    222223333   333334444   444445555   555556666   666667777   777778888   888889999   99999S000   0   1111    TTTTTTTTTTTT    U   V   W   X   Y   Z   !   ",�,$$$$$$,%,&,"  

Jodrell-私はあなたの提案を実装しましたが、ヘッダー出力は次のようになります:

BBBBBBBBBBCCCCCC    CCCCCCCCD   DEFCCCC             GGGGGGGG    HHHHHHH IJJJJJJ     KKKKLLL LLL MMM NNNNNNNNNNNNNNNNNNNNNNNNNNNNN   OOOOOOOOOOOOOOOOOOOOOOOOOOOOO   PPPPQQQQ1111RRRRRRRRRRRRRRRRR   QQQ 111 RRR 33333333    44444444    55555555    66666666    77777777    88888888    99999999    S0000111        111 TTT UVWXYZ!"�$$                                       %&
4

2 に答える 2

2

Jodrellがすでに述べたように、各列ヘッダーを表す文字が異なると想定されているため、コードは機能しません。ヘッダー幅を解析するコードを変更すると修正されます。

交換:

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

と:

var widthList = new List<int>(); 
var header = lines.First().ToArray(); 
for (int i = 0; i < header.Length; i++) 
{ 
    if (i == 0 || header[i] != header[i-1]) 
        widthList.Add(0); 
    widthList[widthList.Count-1]++; 
}

解析されたヘッダー列:

AAAAAAAAAAAAAAAA    BBBBBBBBBB  CCCCCCCC    D   E   F   CCCCCCCCC   GGGGGGGG    HHHHHHHH    I   JJJJJJJJ    KKKK    LLLL    MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM  NNNNNNNNNNNNNNNNNNNNNNNNNNNNNN  OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO  PPPP    QQQQ    1111    RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR    222222222   333333333   444444444   555555555   666666666   777777777   888888888   999999999   S   0000    1111    TTTTTTTTTTTT    U   V   W   X   Y   Z   !   "   £   $$$$$$  %   &
于 2012-10-08T15:43:48.517 に答える
1

編集

"問題が私を悩ませたので、私はとを処理するいくつかのコードを書きました,。このコードは、ヘッダー行をコンマで区切られた交互の0と1に置き換えます。本文内のコンマまたは二重引用符は適切にエスケープされます。

static void FixedToCsv(string sourceFile)
{
    if (sourceFile == null)
    {
        // Throw exception
    }

    var dir = Path.GetDirectory(sourceFile)
    var destFile = string.Format(
        "{0}{1}",
        Path.GetFileNameWithoutExtension(sourceFile),
        ".csv");

    if (dir != null)
    {
        destFile = Path.Combine(dir, destFile);
    }

    if (File.Exists(destFile))
    {
        // Throw Exception
    }

    var blocks = new List<KeyValuePair<int, int>>();
    using (var output = File.OpenWrite(destFile))
    {
        using (var input = File.OpenText(sourceFile))
        {
            var outputLine = new StringBuilder();

            // Make header
            var header = input.ReadLine();

            if (header == null)
            {
                return;
            }

            var even = false;
            var lastc = header.First();
            var counter = 0;
            var blockCounter = 0;
            foreach(var c in header)
            {
                counter++;
                if (c == lastc)
                {
                    blockCounter++;
                }
                else
                {
                    blocks.Add(new KeyValuePair<int, int>(
                        counter - blockCounter - 1,
                        blockCounter));
                    blockCounter = 1;
                    outputLine.Append(',');
                    even = !even;
                }

                outputLine.Append(even ? '1' : '0');

                lastc = c;
            }

            blocks.Add(new KeyValuePair<int, int>(
                counter - blockCounter,
                blockCounter));

            outputLine.AppendLine();
            var lineBytes = Encoding.UTF.GetBytes(outputLine.ToString());
            outputLine.Clear();
            output.Write(lineBytes, 0, lineBytes.Length);

            // Process Body
            var inputLine = input.ReadLine();
            while (inputLine != null)
            {
                foreach(var block in block.Select(b =>
                    inputLine.Substring(b.Key, b.Value)))
                {
                    var sanitisedBlock = block;
                    if (block.Contains(',') || block.Contains('"'))
                    {
                        santitisedBlock = string.Format(
                            "\"{0}\"",
                            block.Replace("\"", "\"\""));
                    }

                   outputLine.Append(sanitisedBlock);
                   outputLine.Append(',');
                }

                outputLine.Remove(outputLine.Length - 1, 1);
                outputLine.AppendLine();
                lineBytes = Encoding.UTF8.GetBytes(outputLne.ToString());
                outputLine.Clear();
                output.Write(lineBytes, 0, lineBytes.Length);

                inputLine = input.ReadLine();
            }
        }
    }
}

1ヘッダー行で繰り返されるため、2つの4は1つの8としてカウントされ、そこからすべてがうまくいきません。

(sの後に4秒のブロックがあり1、sの後にQ4秒の別のブロックがあります)10

基本的に、ヘッダー行が無効であるか、少なくとも提案されたソリューションでは機能しません。


さて、あなたはこのような何かをすることができます。

public void FixedToCsv(string fullFile)
{
    var lines = File.ReadAllLines(fullFile);
    var firstLine = lines.First();

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

    var innerCounter = 0;
    var outerCounter = 0
    var firstLineChars = firstLine.ToCharArray();
    var lastChar = firstLineChars[0]; 
    foreach(var c in firstLineChars)
    {
        if (c == lastChar)
        {
            innerCounter++;
        }
        else
        {
            widths.Add(new KeyValuePair<int, int>(
                outerCounter
                innerCounter);
            innerCounter = 0;
            lastChar = c;
        }
        outerCounter++;
    }

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

    // Get filePath and fileName from fullFile here.
    File.WriteAllLines(filePath + "\\" + fileName + ".csv", csvLines);
}
于 2012-10-08T09:13:55.847 に答える