use System.IO.FileStream class + System.IO.BinaryReader class to simulate the reading logic

解决方案 »

  1.   

    如思归大哥所讲。逻辑你都有了,用C#实现一点都不难了,你只要学习一下System.IO名称空间里面的文件操作类就可以实现了。
      

  2.   

    这是我转的,但不对,得到的数据不对。 public class QQwry
    {
    public string ErrMessage="";
    public long StartIp =0;
    public long EndIp =0;
    public string Country ="";
    public string Local ="";
    public int CountryFlag =0;
    public long RecordCount=0; private System.IO.FileStream file;
    private long firstStartIp=0;
    private long lastStartIp=0;
    private long endIpOff=0;
    private long tmpOffSet=0; private void getStartIp(long recNo)
    {
    long offSet=firstStartIp + 7 * recNo;
    byte[] b=new byte[offSet+7];
    file.Read(b,Convert.ToInt32(offSet),7);
    endIpOff = Int64.Parse(((char)b[offSet+4]).ToString());
    endIpOff += Int64.Parse(((char)b[offSet+5]).ToString())*256;
    endIpOff += Int64.Parse(((char)b[offSet+6]).ToString())*256*256;
    StartIp = Int64.Parse(((char)b[offSet]).ToString());
    StartIp += Int64.Parse(((char)b[offSet+1]).ToString())*256;
    StartIp += Int64.Parse(((char)b[offSet+2]).ToString())*256*256;
    StartIp += Int64.Parse(((char)b[offSet+3]).ToString())*256*256*256;
    } private void getEndIp()
    {
    byte[] b=new byte[endIpOff+5];
    file.Read(b,Convert.ToInt32(endIpOff),5);
    EndIp = Int64.Parse(((char)b[endIpOff]).ToString());
    EndIp += Int64.Parse(((char)b[endIpOff+1]).ToString())*256;
    EndIp += Int64.Parse(((char)b[endIpOff+2]).ToString())*256*256;
    EndIp += Int64.Parse(((char)b[endIpOff+3]).ToString())*256*256*256;
    CountryFlag=Int32.Parse(((char)b[endIpOff+4]).ToString());
    } private void getCountry()
    {
    switch(CountryFlag)
    {
    case 1:
    break;
    case 2:
    break;
    default:
    break;
    }
    } private string getFlagStr(long offSet)
    {
    int flag=0;
    while(true)
    {
    byte[] b=new byte[offSet+1];
    file.Read(b,Convert.ToInt32(offSet),1);
    flag=Int32.Parse(b[offSet].ToString());
    if(flag==1 || flag==2)
    {
    byte[] b2=new byte[offSet+3];
    if(flag==2)
    {
    CountryFlag=2;
    endIpOff=offSet-4;
    }
    offSet = Int64.Parse(((char)b2[offSet]).ToString());
    offSet += Int64.Parse(((char)b2[offSet+1]).ToString())*256;
    offSet += Int64.Parse(((char)b2[offSet+2]).ToString())*256*256;
    }
    else
    {
    break;
    }
    }
    if(offSet<12)
    return "";
    tmpOffSet=offSet;
    return getStr();
    } private string getStr()
    {
    string str="";
    while(true)
    {
    byte[] b=new byte[tmpOffSet+1];
    file.Read(b,Convert.ToInt32(tmpOffSet),1);
    if(Int32.Parse(((char)b[tmpOffSet]).ToString()) == 0)
    break;
    str=str + ((char)b[tmpOffSet]).ToString();
    tmpOffSet++;
    }
    return str;
    } public bool FoundErr
    {
    get
    {
    if(ErrMessage!="")
    return true;
    else
    return false;
    }
    }
    public QQwry(string sip,string FilePath)
    {
    long ip=Ip2Int(sip);
    long recNo;
    try
    {
    file=File.Open(FilePath,FileMode.Open);
    }
    catch
    {
    ErrMessage="打开文件错误!";
    return;
    }
    byte[] b=new byte[8];
    file.Read(b,0,8);
    firstStartIp=Int64.Parse(b[0].ToString()) + Int64.Parse(b[1].ToString())*256 + Int64.Parse(b[2].ToString())*256*256 + Int64.Parse(b[3].ToString())*256*256*256 ;
    lastStartIp=Int64.Parse(b[4].ToString()) + Int64.Parse(b[5].ToString())*256 + Int64.Parse(b[6].ToString())*256*256 + Int64.Parse(b[7].ToString())*256*256*256 ;
    RecordCount=(lastStartIp-firstStartIp) / 7;
    if(RecordCount<=1)
    {
    Country ="无记录";
    file.Close();
    return;
    }
    long rangB=0;
    long rangE=RecordCount;
    while(rangB<rangE-1)
    {
    recNo=(rangB+rangE)/2;
    getStartIp(recNo);
    if(ip==StartIp)
    {
    rangB=recNo;
    break;
    }
    if(ip>StartIp)
    rangB=recNo;
    else
    rangE=recNo;
    }
    getStartIp(rangB);
    getEndIp();
    if((StartIp<=ip) && (EndIp>=ip))
    {
    getCountry(); }
    else
    {
    Country="未知";
    Local="";
    }
    file.Close();
    }
    public long Ip2Int(string sip)
    {
    string[] saip=sip.Split(".".ToCharArray(),4);
    long[] ip=new long[4];
    int i=0;
    for(i=0;i<saip.Length-1;i++)
    {
    ip[i]=Int64.Parse(saip[i]);
    }
    long nip;
    nip=ip[0];
    nip+=ip[1]*256;
    nip+=ip[2]*256*256;
    nip+=ip[3]*256*256*256;
    return nip;
    }
    public string Int2Ip(long nip)
    {
    long b1,b2,b3,b4;
    b1=(nip & 0xff000000) >> 24;
    if(b1<0) b1+=0x100;
    b2=(nip & 0x00ff0000) >> 16;
    if (b2<0) b2+=0x100;
    b3=(nip & 0x0000ff00)>>8;
    if (b3<0) b3+=0x100;
    b4= nip & 0x000000ff;
    if (b4<0) b4+=0x100;
    string ip;
    ip=b1.ToString() + "." + b2.ToString() + "." + b3.ToString() + "." + b3.ToString();
    return ip;
    }
    }
      

  3.   

    我转一个delphi的,现在就缺.net的了。各位兄兄努力啊
    =============================================================
    unit qqwry; 
     
    interface 
     
    uses Classes,Types,SysUtils,Math,dialogs; 
     
    type 
      TQQwry = class 
      public 
        StartIP:DWORD; 
        EndIP:DWORD; 
        Country:string; 
        Local:string; 
        CountryFlag:integer; // 标识 Country位置 
                              // 0x01,随后3字节为Country偏移,没有Local 
                              // 0x02,随后3字节为Country偏移,接着是Local 
                              // 其他,Country,Local,Local有类似的压缩。可能多重引用。 
        FirstStartIp:DWORD; 
        LastStartIp:DWORD; 
        EndIpOff:integer; 
        fHandle:integer; 
        datafile:string; 
        //FileLen:integer; 
        constructor Create(dbfile:string);virtual; 
        destructor Destroy;override; 
     
        function qqwry(dotip:string):integer; 
     
      private 
        function IpToInt(ip:string):DWORD; 
        function IntToIp(ipint:integer):string; 
        function toInt(doint:integer):integer; 
        function GetStartIp(RecNo:integer):DWORD; 
        function GetEndIp():DWORD; 
        function GetStr():string; 
        function getFlagStr(offset:integer):string; 
        procedure getCountry(); 
    end; 
     
    implementation 
     
    function Tqqwry.IpToInt(ip:string):DWORD; 
    var 
      str:TStringList; 
    begin 
      str:=TStringList.Create; 
      str.CommaText:=stringreplace(ip,'.',' ',[rfReplaceAll]); 
      result:=(StrToInt(str.Strings[0]) * 256*256*256) 
                + (StrToInt(str.Strings[1])*256*256) 
                + (StrToInt(str.Strings[2])*256) 
                + StrToInt(str.Strings[3]); 
      str.Free; 
    end; 
     
    function Tqqwry.IntToIp(ipint:integer):string; 
    var 
      b1,b2,b3,b4:integer; 
    begin 
        b1:=(ipint and $ff000000)shr 24; 
        if (b1<0) then b1:=b1+$100; 
        b2:=(ipint and $00ff0000)shr 16; 
        if (b2<0) then b2:=b2+$100; 
        b3:=(ipint and $0000ff00)shr 8; 
        if (b3<0) then b3:=b3+$100; 
        b4:= ipint and $000000ff; 
        if (b4<0) then b4:=b4+$100; 
        result:=inttostr(b1)+'.'+inttostr(b2)+'.'+inttostr(b3)+'.'+inttostr(b4); 
    end; 
     
    constructor TQQwry.Create(dbfile:string); 
    begin 
        StartIP:=0; 
        EndIP:=0; 
        CountryFlag:=0; 
        FirstStartIp:=0; 
        LastStartIp:=0; 
        EndIpOff:=0; 
        datafile:='QQWry.Dat'; 
        if(dbfile<>'') then 
            datafile:=dbfile; 
    end; 
     
    destructor Tqqwry.Destroy; 
    begin 
      if fhandle<>0 then FileClose(fHandle); 
     
    end; 
     
    function Tqqwry.toInt(doint:integer):integer; 
    begin 
      result:=doint; 
      if doint<0 then result:=result+256; 
    end; 
     
    function Tqqwry.GetStartIp(RecNo:integer):DWORD; 
    var 
      offset:dword; 
      buf:array[0..7]of char; 
    begin 
        offset := FirstStartIp + RecNo * 7 ; 
        fileseek ( fhandle , offset, 0 ) ; 
        fileread ( fhandle,buf,7) ; 
     
        EndIpOff := toint(ord(buf[4])) 
                    + (toint(ord(buf[5]))*256 ) 
                    + (toint(ord(buf[6]))* 256*256); 
        StartIP := toint(ord(buf[0])) 
                    + (toint(ord(buf[1]))*256) 
                    + (toint(ord(buf[2]))*256*256) 
                    + (toint(ord(buf[3]))*256*256*256); 
        result:=StartIP ; 
    end; 
     
    function tqqwry.GetEndIp():DWORD; 
    var 
      buf:array[0..4]of char; 
    begin 
      FileSeek(fhandle,endipoff,0); 
      FileRead( fhandle,buf,5); 
      EndIP := toint(ord(buf[0])) + (toint(ord(buf[1]))*256) + (toint(ord(buf[2]))*256*256) + (toint(ord(buf[3]))*256*256*256); 
      CountryFlag := ord ( buf[4] ) ; 
      result:=EndIP ; 
    end; 
     
    function tqqwry.GetStr():string; 
    var 
      c:integer; 
      buf:byte; 
    begin 
      result:=''; 
      while true do 
      begin 
        c:=FileRead(fhandle,buf,1); 
        if toint(buf)=0 then break; 
        result:=result+chr(buf); 
      end; 
    end; 
     
    function tqqwry.getFlagStr(offset:integer):string; 
    var 
      flag:integer; 
      buf:Byte; 
      buffer:array[0..2]of byte; 
    begin 
     
      while true do 
      begin 
        FileSeek(fhandle,offset,0); 
        FileRead(fhandle,buf,1); 
        flag:=toint(buf); 
        if((flag=1)or(flag=2))then 
        begin 
          FileRead(fhandle,buffer,3); 
          if flag=2 then 
          begin 
            CountryFlag := 2 ; 
            EndIpOff := offset - 4 ; 
          end; 
          offset := toint(ord(buffer[0])) + (toint(ord(buffer[1]))*256) + (toint(ord(buffer[2]))* 256*256); 
        end else break; 
      end; 
      if offset<12 then 
      begin 
        result:=''; 
        exit; 
      end; 
      FileSeek(fhandle,offset,0); 
      result:=getstr(); 
    end; 
     
    procedure tqqwry.getCountry(); 
    begin 
      case CountryFlag of 
      1..2:begin 
                Country := getFlagStr (EndIpOff+4) ; 
                if(1 = CountryFlag) then 
                    Local := '' 
                else 
                    Local := getFlagStr (EndIpOff+8); 
           end; 
      else 
           begin 
                Country := getFlagStr (EndIpOff+4) ; 
     
                Local :=   getFlagStr ( fileseek(fhandle,0,1)) ;//fileseek(fhandle,0,1)获得当前文件指针位置 
           end; 
      end; 
    end; 
     
     
     
    function tqqwry.qqwry(dotip:string):integer; 
    var 
      nRet:integer; 
      ip:DWORD; 
      buf:array[0..7]of char; 
      RecintCount,RangB,RangE,RecNo:integer; 
    begin 
      fHandle:=FileOpen(datafile,fmOpenRead); 
     
      if fHandle=0 then 
      begin 
        showmessage('wrong'); 
        result:=-1; 
        exit; 
      end; 
      //filelen:=fileseek(fhandle,0,2); 
      ip:= IpToInt ( dotip ); 
      FileSeek(fhandle,0,0); 
      fileRead(fhandle,buf,8); 
      FirstStartIp := toint(ord(buf[0])) + ((toint(ord(buf[1])))*256) + (toint(ord(buf[2]))*256*256) + (toint(ord(buf[3]))*256*256*256); 
      LastStartIp  := toint(ord(buf[4])) + (toint(ord(buf[5]))*256) + (toint(ord(buf[6]))*256*256) + (toint(ord(buf[7]))*256*256*256); 
     
      RecintCount := floor( ( LastStartIp - FirstStartIp ) / 7); 
     
    //  showmessage(inttostr(RecintCount)+','+inttostr(LastStartIp)); 
      if (RecintCount <= 1) then 
      begin 
            Country := 'FileDataError'; 
            result:=2 ; 
            exit; 
      end; 
      RangB:= 0; 
      RangE:= RecintCount; 
      while (RangB < RangE-1) do 
      begin 
        RecNo:= floor((RangB + RangE) / 2); 
        getStartIp(RecNo); 
        if ip=StartIp then 
        begin 
          RangB:=Recno; 
          break; 
        end; 
        if ip>StartIp then 
          RangB:=RecNo 
        else 
          RangE:=RecNo; 
     
      end;//end of while 
      getStartIp ( RangB ) ; 
      getEndIp ( ) ; 
      if((startip<=ip)and(endip>=ip)) then 
      begin 
        nRet:=0; 
        getCountry(); 
      end else begin 
        nRet:=3; 
        Country:='未知'; 
        Local:=''; 
      end; 
      result:=nRet; 
    end; 
     
    end. 
      

  4.   

    我写出来了:
    http://www.cnblogs.com/rexsp/archive/2004/12/27/82740.html