我有N个文本格式的数据文件(file1、file2....fileN),每个文件大小不一,每行都是一个数据.我想在程序中把这些数据全部读入到数组mydata[]变量中,便于需要数据处理时调用,考虑解决的最好办法是通过二维动态数据组来实现.可不知道具体如何编程实现,特向各位老师求教,敬请指点迷津,最好能提供数组声明和赋值\调用代码,谢谢.

解决方案 »

  1.   

    TFile = class
      private
        FName: String;
        FStream: TMemoryStream;
      protected
        procedure DoLoadFile(FileName: String); virtual;
        procedure DoSaveFile(FileName: String); virtual;
      public
        constructor Create; virtual;
        destructor Destroy; override;
        procedure LoadFromFile(FileName: String);
        procedure SaveToFile(FileName: String = '');
        property FileName: String read FName write FName;
      end;  TTxtFile = class(TFile)
      private
        FStrList: TStringList;
        function GetFileContent: String;
        procedure SetFileContent(const Value: String);
      protected
        procedure DoLoadFile(FileName: String); override;
        procedure DoSaveFile(FileName: String); override;
      public
        constructor Create; override;
        destructor Destroy; override;
        property FileContent: String read GetFileContent write SetFileContent;
      end;  TFileList = class
      private
        FList: TList;
        FItemClass: TClass;
        function GetItems(Index: Integer): TFile;
        procedure SetItems(Index: Integer; const Value: TFile);
      public
        constructor Create; virtual;
        destructor Destroy; override;
        procedure LoadFile(FileName: String);
        procedure SaveAllFile;
        property Items[Index: Integer] :TFile read GetItems write SetItems;
      end;  TTxtFileList = class(TFileList)
      private
        function GetItems(Index: Integer): TTxtFile;
        procedure SetItems(Index: Integer; const Value: TTxtFile);
      public
        constructor Create; override;
        property Items[Index: Integer] :TTxtFile read GetItems write SetItems;
      end;
      

  2.   

    { TFile }constructor TFile.Create;
    begin
      inherited;
      FStream := TMemoryStream.Create;
    end;destructor TFile.Destroy;
    begin
      FreeAndNil(FStream);
      inherited;
    end;procedure TFile.DoLoadFile(FileName: String);
    begin
      FStream.LoadFromFile(FileName);
    end;procedure TFile.DoSaveFile(FileName: String);
    begin
      FStream.SaveToFile(FileName);
    end;procedure TFile.LoadFromFile(FileName: String);
    begin
      FName := FileName;
      DoLoadFile(FileName);
    end;procedure TFile.SaveToFile(FileName: String);
    begin
      if FileName = '' then
      begin
        FName := FileName;
        DoSaveFile(FName);
      end
      else
        DoSaveFile(FileName);
    end;{ TTxtFile }constructor TTxtFile.Create;
    begin
      inherited;
      FStrList := TStringList.Create;
    end;destructor TTxtFile.Destroy;
    begin
      FreeAndNil(FStrList);
      inherited;
    end;procedure TTxtFile.DoLoadFile(FileName: String);
    begin
      inherited;
      FStrList.LoadFromStream(FStream);
    end;procedure TTxtFile.DoSaveFile(FileName: String);
    begin
      FStrList.SaveToStream(FStream);
      inherited;
    end;function TTxtFile.GetFileContent: String;
    begin
      Result := FStrList.Text;
    end;procedure TTxtFile.SetFileContent(const Value: String);
    begin
      if Value <> FStrList.Text then
        FStrList.Text := Value;
    end;{ TFileList }constructor TFileList.Create;
    begin
      inherited;
      FItemClass := TFile;
      FList := FList.Create;
      FList.Capacity := 256;
    end;destructor TFileList.Destroy;
    var
      I: Integer;
    begin
      for I := 0 to FList.Count - 1 do
        TObject(FList[I]).Free;
      FreeAndNil(FList);
      inherited;
    end;function TFileList.GetItems(Index: Integer): TFile;
    begin
      Result := nil;
      if (Index >= 0) and (Index < FList.Count - 1) then
        Result := FList[Index];
    end;procedure TFileList.LoadFile(FileName: String);
    var
      AFile: TObject;
    begin
      AFile := FItemClass.NewInstance;
      AFile := AFile.Create;
      TFile(AFile).LoadFromFile(FileName);
      FList.Add(AFile);
    end;procedure TFileList.SaveAllFile;
    var
      I: Integer;
      TempFile: TFile;
    begin
      for I := 0 to FList.Count - 1 do
      begin
        TempFile := FList[I];
        TempFile.SaveToFile;
      end;
    end;procedure TFileList.SetItems(Index: Integer; const Value: TFile);
    begin
      if (Index >= 0) and (Index < FList.Count - 1) then
      begin
        TObject(FList[Index]).Free;
        FList[Index] := Value;
      end else
        FList.Add(Value);
    end;{ TTxtFileList }constructor TTxtFileList.Create;
    begin
      inherited;
      FItemClass := TTxtFile;
    end;function TTxtFileList.GetItems(Index: Integer): TTxtFile;
    begin
      Result := nil;
      Inherited GetItems(Index);
    end;procedure TTxtFileList.SetItems(Index: Integer; const Value: TTxtFile);
    begin
      Inherited SetItems(Index, Value);
    end;
      

  3.   

    楼主的意思是不是这样的: mydata[0,0] 存放的是第一个文件中的第1行的内容!
      

  4.   

    修罗好厉害啊,崇拜ing。我崇拜那些对类操纵熟练的人。我只会使用不会构造:(
      

  5.   

    这样回答问题,精神可嘉啊。
    我想 就是利用TList容器来存取文件,可以简化一些。
      

  6.   

    楼主的意思是不是这样的: mydata[0,0] 存放的是第一个文件中的第1行的内容!是的,因为我需要对数据相互间进行比较和统计操作,因为,放到一个二维数组中比较方便。WGYKING(修罗是谁?!) 的解答很详细,可惜太复杂了,有没有简便的方法呢?
      

  7.   

    类型:Array of Array of String
    改变长度:SetLength这样的确够简单
    ^_^
      

  8.   

    有简单的方法啊如果想操作文件有几个办法用 CreateFileMapping 建立一个文件句柄, 这个跟 FileOpen 返回的句柄没什么区别
    然后用 MapViewOfFile, 把文件句柄印射成一个指针来操作
    记得要在用完后 UnmapViewOfFile 和 CloseHandle要不然就干脆用 TStringList, 这个是读入内存的,不过跟你的方法没什么区别
    StringList.LoadFromFile(...)哈
    StringList[0] 是第一行
      

  9.   

    //简单实现,献丑 
    type
     TTxtFileList=Class(TStringList)
     private
       function Get(index1,index2:integer):String;virtual;
     public
        Constructor Create;
        Function LoadFile(FileName:Array of String):Boolean;
        destructor destroy;override;
        property Files[index1,index2:integer]: String read Get; default;
     end;Constructor TTxtFileList.Create;
    begin
        inherited;
    end;
    destructor TTxtFileList.destroy;
    var i:integer;
    begin
        for i:=0 to Count-1 do
          TStringList(Objects[i]).Free;
        inherited;
    end;
    function TTxtFileList.Get(index1,index2:integer):String;
    begin
        if (Index1<0) or (Index1>=Count) then
           Raise exception.Create('index1 out of range!');
        if (Index2<0) or (Index2>=TStrings(Objects[Index1]).Count) then
           Raise exception.Create('index2 out of range!');
        Result:=TStrings(Objects[Index1])[index2];end;function TTxtFileList.LoadFile(FileName:Array of String):Boolean;
    var i:integer;
    begin
        ReSult:=false;
        for i:=Low(FileName) to High(FileName) do
        begin
            AddObject(FileName[i],TStringList.Create);
            try
              TStringList(objects[i]).LoadfromFile(FileName[i]);
            except
                 ShowMessage(Filename[i]+'not found!');
                 exit;
            end;
        end;
        Result:=True;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var aa:TTxtFileList;
    begin
      aa:=TTxtFileList.Create;  aa.LoadFile(['c:\temp\testa_d.pas','c:\temp\testa.pas']) ;
      edit1.Text:=aa[0,0];  aa.Free;end;
      

  10.   

    如果你的代码想用类操作就用修罗的方法,
    否则用TStringlist就可以搞定了,而且该类有许多有用的操作如indexof等等
      

  11.   

    哈哈,高手指点下问题解决了,其实很简单,设为n个文件var
      mydata:array of array of stringbegin
      setlength(mydata,n);
      for k:=0 to high(mydata) do
        begin
          setlength(mydata[k],x);//x为第k+1个文件行数
          //这里写代码,将第k+1个文件的数据逐行读入mydata[k]
          mydata[k,0]:=...
          mydata[k,1]:=...
          ...
          mydata[k,x-1]:=...
        end;end;