java实现对纯真IP数据库的查询

来源:http://www.blogjava.net/lcs868/archive/2008/12/16/246644.html

用java实现对纯真IP数据库的查询,首先到网上下载QQwry.da文件,读取代码如下:

1.IP记录实体类

package com.guess.tools; /** *
* 一条IP范围记录,不仅包括国家和区域,也包括起始IP和结束IP * *
 * @author swallow */
public class IPEntry {
    public String beginIp;
    public String endIp;
    public String country;
    public String area; /** *//**
     * 构造函数
     */ public IPEntry() {
        beginIp = endIp = country = area = "";
    } public String toString(){
       return        this.area+"  "+this.country+"IP范围:"+this.beginIp+"-"+this.endIp;
    }
   }



2.读取QQwry.dat文件类


package com.guess.tools; import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteOrder;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List; /** *//**
 *  * 用来读取QQwry.dat文件,以根据ip获得好友位置,QQwry.dat的格式是
 * 一. 文件头,共8字节
 *        1. 第一个起始IP的绝对偏移, 4字节
 *     2. 最后一个起始IP的绝对偏移, 4字节
 * 二. "结束地址/国家/区域"记录区
 *     四字节ip地址后跟的每一条记录分成两个部分
 *     1. 国家记录
 *     2. 地区记录
 *     但是地区记录是不一定有的。而且国家记录和地区记录都有两种形式
 *     1. 以0结束的字符串
 *     2. 4个字节,一个字节可能为0x1或0x2
 *           a. 为0x1时,表示在绝对偏移后还跟着一个区域的记录,注意是绝对偏移之后,而不是这四个字节之后
 *        b. 为0x2时,表示在绝对偏移后没有区域记录
 *        不管为0x1还是0x2,后三个字节都是实际国家名的文件内绝对偏移
 *           如果是地区记录,0x1和0x2的含义不明,但是如果出现这两个字节,也肯定是跟着3个字节偏移,如果不是
 *        则为0结尾字符串
 * 三. "起始地址/结束地址偏移"记录区
 *     1. 每条记录7字节,按照起始地址从小到大排列
 *        a. 起始IP地址,4字节
 *        b. 结束ip地址的绝对偏移,3字节
 *
 * 注意,这个文件里的ip地址和所有的偏移量均采用little-endian格式,而java是采用
 * big-endian格式的,要注意转换
 *
 *
 * @author 马若劼
 */
public class IPSeeker {
    /** *//**
     *      * 用来封装ip相关信息,目前只有两个字段,ip所在的国家和地区
     *
     *
     * @author swallow     */
    private class IPLocation {
        public String country;
        public String area; public IPLocation() {
            country = area = "";
        } public IPLocation getCopy() {
            IPLocation ret = new IPLocation();
            ret.country = country;
            ret.area = area;
            return ret;
        }
    } private static final String IP_FILE = IPSeeker.class.getResource("/QQWry.DAT").toString().substring(5); // 一些固定常量,比如记录长度等等
    private static final int IP_RECORD_LENGTH = 7;
    private static final byte AREA_FOLLOWED = 0x01;
    private static final byte NO_AREA = 0x2; // 用来做为cache,查询一个ip时首先查看cache,以减少不必要的重复查找
    private Hashtable ipCache;
    // 随机文件访问类
    private RandomAccessFile ipFile;
    // 内存映射文件
    private MappedByteBuffer mbb;
    // 单一模式实例
    private static IPSeeker instance = new IPSeeker();
    // 起始地区的开始和结束的绝对偏移
    private long ipBegin, ipEnd;
    // 为提高效率而采用的临时变量
    private IPLocation locborder-bottom-style: none; padding-bottom: 0px; border-right-style: none; margin: 0px; padding-left: 0px; padding-right: 0px; font-family: verdana, arial, helvetica, sans-serif;
  
分享到:
评论

你可能感兴趣的:(java,.net,cache)