1

特定の文字を使用してファイルを分割する必要があるという要件があります。デフォルトの分割オプションは、CRLF、LF、およびCRです。

これらの場合、私は行をそれぞれ\ r\nと\nと\rで分割しています。

また、任意のサイズのファイルを処理する必要があるという要件があります。(処理とは、基本的に、指定された文字列をファイルの指定された位置に挿入することです)。

このために、私は1024バイトのチャンクでファイルを読み取っています。

次に、string.Split()メソッドを適用します。Split()メソッドは、空白を無視するためのオプションを提供します。

これらの改行文字を行に追加し直す必要があります。このために、私はバイナリライターを使用しており、バイト配列を新しいファイルに書き込んでいます。問題:-

1)改行がCRLFで、分割オプションがNONEの場合、分割された配列にスペースも追加されます。2番目のオプションが指定されています(空白を無視するため)CRLFは正しく機能します。

2)空白を無視するビットオプションは、ファイルをバイト単位で読み取っているため、空白を無視できないため、他の問題を引き起こします。

3)改行文字がデフォルト以外の場合(例:'|')、結果の行にnull値が付加されます。

誰かが私の問題の解決策を与えることができますか?

これが私が書いた方法です

    private static void ProcessOriginalFile(string filePath, string destinationFilePath, int fromPosition, int toPosition, string lineBreakCharacter, string replaceString, long fileSize, bool ignoreHeader, bool ignoreFooter)
    {
        int chunkSize = fileSize < 1024 ? (int)fileSize : 1024;//bytes
        byte[] chunkData = new byte[chunkSize];
        char[] charactersSeparator=new char[1];

        charactersSeparator = CommonOperations.ResolveTheRecordBreak(lineBreakCharacter);           

        int totalLineBreakCharactersLength = 0;
        for (int i = 0; i < charactersSeparator.Length; i++)
        {
            if (charactersSeparator[i] == 0)
                break;
            totalLineBreakCharactersLength = totalLineBreakCharactersLength + BitConverter.GetBytes(charactersSeparator[i]).Length;
        }


            using (BinaryReader fileReader = new  BinaryReader(new FileStream(filePath, FileMode.Open)))
            {
                string lastChunk = string.Empty;
                string chunkcontents = string.Empty;
                IList<byte[]> dataToBeWritten = new List<byte[]>();

                while (fileSize > 0)
                {
                    chunkData = fileReader.ReadBytes(chunkSize);
                    byte[] chunkToBeWritten = new byte[chunkSize];
                    chunkcontents = chunkcontents + System.Text.ASCIIEncoding.UTF8.GetString(chunkData);

                    string[] splittedArray = new string[1];
                        splittedArray = chunkcontents.Split(charactersSeparator, StringSplitOptions.RemoveEmptyEntries);
                        if (ignoreHeader)
                        {
                            splittedArray = splittedArray.Skip(1).ToArray();
                            ignoreHeader = false;
                            if (splittedArray.Count() == 0)
                                continue;
                        }

                    int count = 0;
                    if (splittedArray != null || splittedArray.Count() > 0)
                    {
                        foreach (string str in splittedArray)
                        {
                            ++count;
                            if (count != splittedArray.Length)
                            {
                                string stringToBeEdited = string.Empty;
                                stringToBeEdited = str;
                                if (stringToBeEdited.Length < (toPosition + 1))
                                    throw new Exception("Position exceeds the string length. Line contents are : " + stringToBeEdited + " String length is : " + stringToBeEdited.Length + " To Position is : " + toPosition);
                                //replace the text between from and two positions with the replaced string
                                stringToBeEdited = stringToBeEdited.Remove(fromPosition, toPosition + 1 - fromPosition).Insert(fromPosition, replaceString);

                                //clear the array
                                dataToBeWritten.Clear();
                                AddLineBreakCharacter(lineBreakCharacter, charactersSeparator, totalLineBreakCharactersLength, dataToBeWritten, ref chunkToBeWritten, ref stringToBeEdited);

                                //write data using binary writer
                                WriteBinaryDataToFile(destinationFilePath, dataToBeWritten);
                                totalLinesProcessed++;
                            }
                            else
                            {
                                lastChunk = str;
                                chunkcontents = str;
                            }
                        }
                    }
                    fileSize = fileSize - chunkSize;

                    /*if file size is less than the chunksize*2, then chunk size should be the file size 
                     * and chunkdata array length should be that of the file size*/

                    if (fileSize < (chunkSize * 2))
                    {
                        chunkSize = (int)fileSize;
                        chunkData = new byte[chunkSize];
                    }
                }


                if (!string.IsNullOrEmpty(lastChunk))
                {
                    if (ignoreFooter == false)
                    {
                        if (lastChunk.Length >= toPosition + 1)
                            lastChunk = lastChunk.Remove(fromPosition, toPosition + 1 - fromPosition).Insert(fromPosition, replaceString);
                        else
                            throw new Exception("Position exceeds in the last line of the file. Line contents are : " + lastChunk + " String length is : " + lastChunk.Length + " To Position is : " + toPosition);
                        dataToBeWritten.Clear();
                        byte[] chunkToBeWritten = new byte[chunkSize];
                        AddLineBreakCharacter(lineBreakCharacter, charactersSeparator, totalLineBreakCharactersLength, dataToBeWritten, ref chunkToBeWritten, ref lastChunk);
                        WriteBinaryDataToFile(destinationFilePath, dataToBeWritten);
                        totalLinesProcessed++;
                    }
                }
            }
    }

    private static void WriteBinaryDataToFile(string destinationFilePath, IList<byte[]> chunkToBeWritten)
    {
            using (FileStream fileSream = new FileStream(destinationFilePath, FileMode.Append))
            {
                using (BinaryWriter outfile = new BinaryWriter(fileSream, Encoding.ASCII))
                {
                    foreach (byte[] item in chunkToBeWritten)
                    {
                        outfile.Write(item);
                    }
                }
            }
    }

    private static void AddLineBreakCharacter(string lineBreakCharacter, char[] charactersSeparator, int totalLineBreakCharactersLength, IList<byte[]> dataToBeWritten, ref byte[] chunkToBeWritten, ref string stringToBeEdited)
    {
        switch (lineBreakCharacter)
        {
            case CommonConstants.NEW_LINE:
                stringToBeEdited = stringToBeEdited + CommonConstants.CARRIAGE_RETURN_CHARACTER + CommonConstants.NEW_LINE_CHARACTER;
                chunkToBeWritten = System.Text.Encoding.UTF8.GetBytes(stringToBeEdited);
                //add modified line 
                dataToBeWritten.Add(chunkToBeWritten);
                break;

            case CommonConstants.LINE_FEED:
                stringToBeEdited = stringToBeEdited + CommonConstants.NEW_LINE_CHARACTER;
                chunkToBeWritten = System.Text.Encoding.UTF8.GetBytes(stringToBeEdited);
                //add modified line 
                dataToBeWritten.Add(chunkToBeWritten);

                break;
            case CommonConstants.CARRIAGE_RETURN:
                stringToBeEdited = stringToBeEdited + CommonConstants.CARRIAGE_RETURN_CHARACTER;
                chunkToBeWritten = System.Text.Encoding.UTF8.GetBytes(stringToBeEdited);
                //add modified line 
                dataToBeWritten.Add(chunkToBeWritten);

                break;
            default:
                chunkToBeWritten = System.Text.Encoding.UTF8.GetBytes(stringToBeEdited);
                //add modified line 
                dataToBeWritten.Add(chunkToBeWritten);

                byte[] seperatorCharArray = new byte[totalLineBreakCharactersLength];
                int destinationIndex = 0;
                foreach (char ch in charactersSeparator)
                {
                    if (ch == 0)
                        break;
                    //convert the character to byte array
                    byte[] charArr = BitConverter.GetBytes(ch);

                    //copy character bytes to seperator character array                        
                    Array.Copy(charArr, 0, seperatorCharArray, destinationIndex, charArr.Length);
                }
                //add line break characters array to list
                dataToBeWritten.Add(seperatorCharArray);
                break;
        }
    }
4

2 に答える 2

0

分割する前に、問題のシンボルを使用string.Replaceして置き換えることができます""

于 2012-12-07T05:01:21.877 に答える
0

問題を解決しました。上記のコードをダンプし、TextReaderを使用してファイルを1文字ずつ読み取りました。同時に、改行文字をチェックしました。私はそれを手に入れたらすぐに、ラインを処理しました。

于 2012-12-14T05:30:16.220 に答える