【问题标题】:Best way to handle huge strings in C#在 C# 中处理大字符串的最佳方法
【发布时间】:2010-05-31 07:55:42
【问题描述】:

在用##IP##、##PORT## 替换两个值后,我必须将以下数据写入文本文件。 什么是最好的方法?我应该将所有内容保存在一个字符串中并使用替换并写入文本文件吗?

数据:

[APP]
    iVersion=   101
    pcVersion=  1.01a
    pcBuildDate=Mar 27 2009
[MAIN]
    iFirstSetup=        0
    rcMain.rcLeft=    676
    rcMain.rcTop=     378
    rcMain.rcRight=  1004
    rcMain.rcBottom=  672
    iShowLog=           0
    iMode=              1
[GENERAL]
    iTips=              1
    iTrayAnimation=     1
    iCheckColor=        1
    iPriority=          1
    iSsememcpy=         1
    iAutoOpenRecv=      1
    pcRecvPath=         C:\Documents and Settings\karthikeyan\My Documents\Downloads\fremote101a\FantasyRemote101a\recv
    pcFileName=         FantasyRemote
    iLanguage=          1
[SERVER]
    iAcceptVideo=       1
    iAcceptAudio=       1
    iAcceptInput=       1
    iAutoAccept=        1
    iAutoTray=          0
    iConnectSound=      1
    iEnablePassword=    0
    pcPassword=
    pcPort=          7902
[CLIENT]
    iAutoConnect=       0
    pcPassword=
    pcDefaultPort=   7902
[NETWORK]
    pcConnectAddr=##IP##
    pcPort=##Port##
[VIDEO]
    iEnable=                  1
    pcFcc=                 AMV3
    pcFccServer=           
    pcDiscription=         
    pcDiscriptionServer=   
    iFps=                    30
    iMouse=                   2
    iHalfsize=                0
    iCapturblt=               0
    iShared=                  0
    iSharedTime=              5
    iVsync=                   1
    iCodecSendState=          1
    iCompress=                2
    pcPlugin=              
    iPluginScan=              0
    iPluginAspectW=          16
    iPluginAspectH=           9
    iPluginMouse=             1
    iActiveClient=            0
    iDesktop1=                1
    iDesktop2=                2
    iDesktop3=                0
    iDesktop4=                3
    iScan=                    1
    iFixW=                   16
    iFixH=                    8
[AUDIO]
    iEnable=                  1
    iFps=                    30
    iVolume=                  6
    iRecDevice=               0
    iPlayDevice=              0
    pcSamplesPerSec=    44100Hz
    pcChannels=      2ch:Stereo
    pcBitsPerSample=      16bit
    iRecBuffNum=            150
    iPlayBuffNum=             4
[INPUT]
    iEnable=                  1
    iFps=                    30
    iMoe=                     0
    iAtlTab=                  1
[MENU]
    iAlwaysOnTop=             0
    iWindowMode=              0
    iFrameSize=               4
    iSnap=                    1
[HOTKEY]
    iEnable=                            1
    key_IDM_HELP=              0x00000070
    mod_IDM_HELP=              0x00000000
    key_IDM_ALWAYSONTOP=       0x00000071
    mod_IDM_ALWAYSONTOP=       0x00000000
    key_IDM_CONNECT=           0x00000072
    mod_IDM_CONNECT=           0x00000000
    key_IDM_DISCONNECT=        0x00000073
    mod_IDM_DISCONNECT=        0x00000000
    key_IDM_CONFIG=            0x00000000
    mod_IDM_CONFIG=            0x00000000
    key_IDM_CODEC_SELECT=      0x00000000
    mod_IDM_CODEC_SELECT=      0x00000000
    key_IDM_CODEC_CONFIG=      0x00000000
    mod_IDM_CODEC_CONFIG=      0x00000000
    key_IDM_SIZE_50=           0x00000074
    mod_IDM_SIZE_50=           0x00000000
    key_IDM_SIZE_100=          0x00000075
    mod_IDM_SIZE_100=          0x00000000
    key_IDM_SIZE_200=          0x00000076
    mod_IDM_SIZE_200=          0x00000000
    key_IDM_SIZE_300=          0x00000000
    mod_IDM_SIZE_300=          0x00000000
    key_IDM_SIZE_400=          0x00000000
    mod_IDM_SIZE_400=          0x00000000
    key_IDM_CAPTUREWINDOW=     0x00000077
    mod_IDM_CAPTUREWINDOW=     0x00000004
    key_IDM_REGION=            0x00000077
    mod_IDM_REGION=            0x00000000
    key_IDM_DESKTOP1=          0x00000078
    mod_IDM_DESKTOP1=          0x00000000
    key_IDM_ACTIVE_MENU=       0x00000079
    mod_IDM_ACTIVE_MENU=       0x00000000
    key_IDM_PLUGIN=            0x0000007A
    mod_IDM_PLUGIN=            0x00000000
    key_IDM_PLUGIN_SCAN=       0x00000000
    mod_IDM_PLUGIN_SCAN=       0x00000000
    key_IDM_DESKTOP2=          0x00000078
    mod_IDM_DESKTOP2=          0x00000004
    key_IDM_DESKTOP3=          0x00000079
    mod_IDM_DESKTOP3=          0x00000004
    key_IDM_DESKTOP4=          0x0000007A
    mod_IDM_DESKTOP4=          0x00000004
    key_IDM_WINDOW_NORMAL=     0x0000000D
    mod_IDM_WINDOW_NORMAL=     0x00000004
    key_IDM_WINDOW_NOFRAME=    0x0000000D
    mod_IDM_WINDOW_NOFRAME=    0x00000002
    key_IDM_WINDOW_FULLSCREEN= 0x0000000D
    mod_IDM_WINDOW_FULLSCREEN= 0x00000001
    key_IDM_MINIMIZE=          0x00000000
    mod_IDM_MINIMIZE=          0x00000000
    key_IDM_MAXIMIZE=          0x00000000
    mod_IDM_MAXIMIZE=          0x00000000
    key_IDM_REC_START=         0x00000000
    mod_IDM_REC_START=         0x00000000
    key_IDM_REC_STOP=          0x00000000
    mod_IDM_REC_STOP=          0x00000000
    key_IDM_SCREENSHOT=        0x0000002C
    mod_IDM_SCREENSHOT=        0x00000002
    key_IDM_AUDIO_MUTE=        0x00000073
    mod_IDM_AUDIO_MUTE=        0x00000004
    key_IDM_AUDIO_VOLUME_DOWN= 0x00000074
    mod_IDM_AUDIO_VOLUME_DOWN= 0x00000004
    key_IDM_AUDIO_VOLUME_UP=   0x00000075
    mod_IDM_AUDIO_VOLUME_UP=   0x00000004
    key_IDM_CTRLALTDEL=        0x00000023
    mod_IDM_CTRLALTDEL=        0x00000003
    key_IDM_QUIT=              0x00000000
    mod_IDM_QUIT=              0x00000000
    key_IDM_MENU=              0x0000007B
    mod_IDM_MENU=              0x00000000
[OVERLAY]
    iIndicator=            1
    iAlphaBlt=             1
    iEnterHide=            0
    pcFont=     MS UI Gothic
[AVI]
    iSound=                    1
    iFileSizeLimit=       100000
    iPool=                     4
    iBuffSize=                32
    iStartDiskSpaceCheck=      1
    iStartDiskSpace=        1000
    iRecDiskSpaceCheck=        1
    iRecDiskSpace=           100
    iCache=                    0
    iAutoOpen=                 1
    pcPath=C:\Documents and Settings\karthikeyan\My Documents\Downloads\fremote101a\FantasyRemote101a\avi
[SCREENSHOT]
    iSound=       1
    iAutoOpen=    1
    pcPath=       C:\Documents and Settings\karthikeyan\My Documents\Downloads\fremote101a\FantasyRemote101a\ss
    pcPlugin=   BMP
[CDLG_SERVER]
    mrcWnd.rcLeft=      667
    mrcWnd.rcTop=       415
    mrcWnd.rcRight=    1013
    mrcWnd.rcBottom=    634
[CWND_CLIENT]
    miShowLog=            0
    m_iOverlayLock=       0
[CDLG_CONFIG]
    mrcWnd.rcLeft=      467
    mrcWnd.rcTop=       247
    mrcWnd.rcRight=    1213
    mrcWnd.rcBottom=    802
    miTabConfigSel=       2

【问题讨论】:

  • 你有没有想过你的浏览器可以流畅地处理这个问题,即使是使用 javascript 添加标记。
  • 最好的办法是不要用 C# 编写工具,而是使用开箱即用的工具。

标签: c#


【解决方案1】:

为什么在我看来它像一个 INI 文件? 尝试使用Nini

编辑:添加示例

这里是如何使用 Nini 库的简单示例。

    using System;
    using Nini;
    using Nini.Ini;
    using Nini.Config;
    using System.IO;

    namespace CommandLine
    {
        class Test
        {
            static void Main(string[] Args)
            {
                string myIniTxt = Path.Combine(Environment.CurrentDirectory, "ini.txt");
                IniConfigSource ini = new IniConfigSource(myIniTxt);
                IConfig config = ini.Configs["NETWORK"];
                config.Set("pcConnectAddr", "myValueForPcConnectAdd");
                config.Set("pcPort", "myValueForPcPort");
                ini.Save();
            }
        }
    }

备注:“Nini”的第一个链接似乎效果不佳,但这里有一些其他链接。

http://sourceforge.net/projects/nini/

http://nini.sourceforge.net/Manual/NiniManual.htm

【讨论】:

  • 您确定与 1.1 之后的 .net 框架兼容吗?
  • @backslash17 我在一个 .NET 3,5 项目中使用 NINI 大约 1 年没有出现错误。
【解决方案2】:

我建议你只是阅读文件并替换。应该没问题。如果您担心性能,我建议您测量性能,如果出现问题,请稍后尝试修复。

示例。

string file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "foo.file");
string s = File.ReadAllText(file);

s = s.Replace("##IP##", "127.0.0.1");
s = s.Replace("##PORT##", "80");

File.WriteAllText(file, s);

【讨论】:

    【解决方案3】:

    我想你可以在这里使用StringBuilder

    StringBuilder 允许您操作/替换同一内存位置中的字符串。

    每次操作字符串时,都会分配新内存来保存结果,而旧字符串会被垃圾回收。 StringBuilder 专门用于制作可变字符串。

    阅读评论后编辑:模板(没有替换的文本)可以放在项目设置中。 IDE 将处理所有其余的工作。

    如果真的很大,最好放在安装文件夹的一个文件里。然后您必须确保该文件与您的应用程序一起安装。

    您将文件“MyTemplate.txt”放在 StringBuilder 中,如下所示:

    var fileName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase )),
        "MyTemplate.txt");
    var stringBuilder = new StringBuilder(File.ReadAllText(fileName));
    

    【讨论】:

    • 但是,我怎样才能将整个数据添加到一个字符串中......因为需要很多转义序列!
    【解决方案4】:

    如果您完全确定文件的大小并且您知道它不会超过几百 MB,那么请在内存中读取它并进行正则表达式替换。但是,为了灵活性,我会一次准备一行文件,进行替换并写出第二个文件。

    【讨论】:

    • 我确定文件大小不会超过。你能举个例子来处理这个吗?
    【解决方案5】:

    我应该将所有内容保存在一个字符串中并使用替换并写入文本文件吗?

    这是要尝试的第一件事。该字符串非常小(不是兆字节),我猜您不会经常这样做或循环执行(您只会这样做一次),并且延迟将只有几分之一秒对你来说没问题,使用StringBuilder 的另一个更复杂的解决方案不会超过两倍。

    【讨论】:

      【解决方案6】:

      您也可以查看:Memory Efficiency and Performance of String.Replace .NET Framework

      您可以执行以下操作来从文件中读取、搜索、替换然后再次写入。

      using System;
      using System.IO;
      using System.Text.RegularExpressions;
      static public void ReplaceInFile( string filePath, string searchText, string replaceText )
      {
          StreamReader reader = new StreamReader( filePath );
          string content = reader.ReadToEnd();
          reader.Close();
      
          content = Regex.Replace( content, searchText, replaceText );
      
          StreamWriter writer = new StreamWriter( filePath );
          writer.Write( content );
          writer.Close();
      }
      

      另请参阅此代码从头开始:http://www.codeproject.com/KB/string/fastestcscaseinsstringrep.aspx

      【讨论】:

        【解决方案7】:

        最好的方法是手动解析文件的内容并使用 StringBuilder 进行替换。

        【讨论】:

        • 有时“最佳”可能意味着“最不明显/最明显的源代码行”,例如使用string.Replace 方法。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-25
        • 2016-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多