写入二进制文件的C#比Delphi

时间:2016-03-11 14:48:18

标签: c# delphi-7 filestream

我将Delphi应用转换为C#。该程序的一部分要求在Delphi中编写许多packed records,或在C#中编写structs到二进制文件。这些文件大约400mb。 Delphi版本已完成写入8 seconds周围的文件,而C#版本大约需要800 seconds。我该怎么做才能提高C#版本的速度?

以下是Delphi版本:

CONST
   RecordSize= 128;
   HeaderSize=128;

TESTrec = packed record
     now: TDateTime;
     //other fields here
     end;

TESThdrrec = packed record
    now: TDateTime;
    Firsttime: TDateTime;
    Lasttime: TDateTime;
    //other fields listed here
    end;

Function TRampBuildForm.CreateTest(FilePath:String;StartTime:TDateTime;EndTime:TDateTime):Boolean;
var
    Records:Int64;
    CurrentOffSet:Int64;
    CurrentTime:TDateTime;
    NewRec:TESTrec;
    NewHeader:TESThdrrec;
    ix:Integer;
    percent:Integer;

begin
    Try
      RampStream:=TFileStream.Create(FilePath,fmCreate OR fmShareExclusive );
    except
      ShowMessage('cannot create Ramp '+Rampname+chr(13)+'Check to see if file is open');
      CreateTest:=false;
    end;
    FillChar(NewHeader,HeaderSize,0);
    NewHeader.now:=Now;
    NewHeader.Firsttime:=StartTime;
    NewHeader.LastTime:= EndTime;
    FirstAllowableTime:=StartTime;
    LastAllowableTime:=EndTime;

    Records:= Round((EndTime-StartTime)/ONE_SECOND)+1;
    RampStream.Write(NewHeader,HeaderSize);

    FillChar(NewRec,RecordSize,0);
    label8.Caption:='Expanding ';
    Progressbar1.Position:=0;
    CurrentTime:=StartTime;
    percent:=0;
    refresh;
    Application.ProcessMessages;
    For ix:= 1 to Records do
    begin
        if (ix*100) div Records > percent then
        begin
            percent:= (ix*100) div Records;
            Progressbar1.position:=percent;
            refresh;
            Application.ProcessMessages
        end;
        NewRec.Now:=CurrentTime;
        RampStream.Write(NewRec,RecordSize);
        CurrentTime:=CurrentTime + ONE_SECOND;
    end;
    ProgressBar1.Position:=100;
    refresh;

    CreateTest:=True;
    RampStream.Free;
end;

我的C#版本:

const int RecordSize = 128;
const int HeaderSize = 128;

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Testrec
{
    public double now;
    //other fields here
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct TESThdrrec
{
    public double now;
    public double Firsttime;
    public double Lasttime;
    //other fields here
}

private Boolean CreateTest(string FilePath, double StartTime, double EndTime)
        {
            long Records;
            long CurrentOffSet;
            double CurrentTime;
            TESTrec NewRec = new TESTrec();
            TESThdrrec NewHeader = new TESThdrrec();
            int ix;
            int percent;

            NewHeader.now = System.DateTime.Now.ToOADate();
            NewHeader.Firsttime = StartTime;
            NewHeader.Lasttime = EndTime;
            FirstAllowableTime = StartTime;
            LastAllowableTime = EndTime;

            if (!File.Exists(FilePath)) //if file doesn't exist
            {
                try
                {
                    using (RampStream = new FileStream(FilePath, FileMode.Create)) 
                    {
                        byte[] buffer = GetBytes2(NewHeader); //puts struct into byte array
                        RampStream.Write(buffer, 0, HeaderSize); //write byte array to file
                    }
                }
                catch (Exception e)
                {
                    System.Windows.MessageBox.Show("Cannot create file" + RampName + Environment.NewLine + "Error Message: " + e);
                }
            }

            Records = (long)(Math.Round((EndTime - StartTime) / ONE_SECOND) + 1);

            RampInfo.Content = "Expanding ";
            ProgressBar1.Value = 0;
            CurrentTime = StartTime;
            percent = 0;

            //TAKING LONG TIME HERE!!
            for (ix = 1; ix <= Records; ix++)
            {
                if (((ix * 100) / Records) > percent)
                {
                    percent = (ix * 100) / (int)Records;
                }
                NewRec.now = CurrentTime;
                using (RampStream = new FileStream(FilePath, FileMode.Open)) 
                {
                    byte[] buffer = GetBytes2(NewRec); //puts struct into byte array
                    RampStream.Write(buffer, 0, RecordSize); //write byte array to file
                }
                //RampStream.Write(NewRec, RecordSize);
                CurrentTime = CurrentTime + ONE_SECOND;
            }

            ProgressBar1.Value = 100;

            RampStream.Close();
            return true;
        }

for loop中正在更新一个进度条,这是代码挂断的地方。我没有刷新它或使用Delphi版本正在使用的FillChar等效物,但我认为这不会影响这个?

1 个答案:

答案 0 :(得分:2)

您正在为每次写入打开和关闭流!在写循环开始时打开文件一次,并在循环结束时关闭它(就像在旧代码中一样)。

(您要确保您仍然使用using语句来关闭该文件。)