Java 统计文件ip,java代码获取IP地址和访问量解析

private IPLocation getIPLocation(int offset) {

// 跳过4字节ip

mbb.position(offset + 4);

// 读取第一个字节判断是否标志字节

byte b = mbb.get();

if(b == REDIRECT_MODE_1) {

// 读取国家偏移

int countryOffset = readInt3();

// 跳转至偏移处

mbb.position(countryOffset);

// 再检查一次标志字节,因为这个时候这个地方仍然可能是个重定向

b = mbb.get();

if(b == REDIRECT_MODE_2) {

loc.setCountry ( readString(readInt3()));

mbb.position(countryOffset + 4);

} else

loc.setCountry ( readString(countryOffset));

// 读取地区标志

loc.setArea(readArea(mbb.position()));

} else if(b == REDIRECT_MODE_2) {

loc.setCountry ( readString(readInt3()));

loc.setArea(readArea(offset + 8));

} else {

loc.setCountry ( readString(mbb.position() - 1));

loc.setArea(readArea(mbb.position()));

}

return loc;

}

private String readArea(long offset) throws IOException {

ipFile.seek(offset);

byte b = ipFile.readByte();

if(b == REDIRECT_MODE_1 || b == REDIRECT_MODE_2) {

long areaOffset = readLong3(offset + 1);

if(areaOffset == 0)

return Message.unknown_area;

else

return readString(areaOffset);

} else

return readString(offset);

}

private String readArea(int offset) {

mbb.position(offset);

byte b = mbb.get();

if(b == REDIRECT_MODE_1 || b == REDIRECT_MODE_2) {

int areaOffset = readInt3();

if(areaOffset == 0)

return Message.unknown_area;

else

return readString(areaOffset);

} else

return readString(offset);

}

private String readString(long offset) {

try {

ipFile.seek(offset);

int i;

for(i = 0, buf[i] = ipFile.readByte(); buf[i] != 0; buf[++i] =

ipFile.readByte());

if(i != 0)

return Util.getString(buf, 0, i, "GBK");

} catch (IOException e) {

LogFactory.log("",Level.ERROR,e);

}

return "";

}

private String readString(int offset) {

try {

mbb.position(offset);

int i;

for(i = 0, buf[i] = mbb.get(); buf[i] != 0; buf[++i] =

mbb.get());

if(i != 0)

return Util.getString(buf, 0, i, "GBK");

} catch (IllegalArgumentExceptione) {

LogFactory.log("",Level.ERROR,e);

}

return "";

}

}

在实际项目用我使用spring注入IP地址库文件的名字和所在目录,并能保证IPSeeker的单一实例。

下面是个工具类,把string和btye数组之间互相转换的类。

Java代码

package com.showtime.IPparse;

import java.io.UnsupportedEncodingException;

import java.util.StringTokenizer;

import org.apache.log4j.Level;

import com.showtime.util.LogFactory;

public class Util {

private static StringBuilder sb = new StringBuilder();

public static byte[] getIpByteArrayFromString(String ip) {

byte[] ret = new byte[4];

StringTokenizer st = new StringTokenizer(ip, ".");

try {

ret[0] = (byte)(Integer.parseInt(st.nextToken()) &

0xFF);

ret[1] = (byte)(Integer.parseInt(st.nextToken()) &

0xFF);

ret[2] = (byte)(Integer.parseInt(st.nextToken()) &

0xFF);

ret[3] = (byte)(Integer.parseInt(st.nextToken()) &

0xFF);

} catch (Exception e) {

LogFactory.log("从ip的字符串形式得到字节数组形式报错", Level.ERROR, e);

}

return ret;

}

public static String getIpStringFromBytes(byte[] ip) {

sb.delete(0, sb.length());

sb.append(ip[0] & 0xFF);

sb.append('.');

sb.append(ip[1] & 0xFF);

sb.append('.');

sb.append(ip[2] & 0xFF);

sb.append('.');

sb.append(ip[3] & 0xFF);

return sb.toString();

}

public static String getString(byte[] b, int offset, int len,

String encoding) {

try {

return new String(b, offset, len, encoding);

} catch (UnsupportedEncodingException e) {

return new String(b, offset, len);

}

}

}

package com.showtime.IPparse;

import java.io.UnsupportedEncodingException;

import java.util.StringTokenizer;

import org.apache.log4j.Level;

import com.showtime.util.LogFactory;

public class Util {

private static StringBuilder sb = new StringBuilder();

public static byte[] getIpByteArrayFromString(String ip) {

byte[] ret = new byte[4];

StringTokenizer st = new StringTokenizer(ip, ".");

try {

ret[0] = (byte)(Integer.parseInt(st.nextToken()) &

0xFF);

ret[1] = (byte)(Integer.parseInt(st.nextToken()) &

0xFF);

ret[2] = (byte)(Integer.parseInt(st.nextToken()) &

0xFF);

ret[3] = (byte)(Integer.parseInt(st.nextToken()) &

0xFF);

} catch (Exception e) {

LogFactory.log("从ip的字符串形式得到字节数组形式报错", Level.ERROR, e);

}

return ret;

}

public static String getIpStringFromBytes(byte[] ip) {

sb.delete(0, sb.length());

sb.append(ip[0] & 0xFF);

sb.append('.');

sb.append(ip[1] & 0xFF);

sb.append('.');

sb.append(ip[2] & 0xFF);

sb.append('.');

sb.append(ip[3] & 0xFF);

return sb.toString();

}

public static String getString(byte[] b, int offset, int len,

String encoding) {

try {

return new String(b, offset, len, encoding);

} catch (UnsupportedEncodingException e) {

return new String(b, offset, len);

}

}

}

下面是个常量值的类,用接口形式来定义省事不少。

Java代码

package com.showtime.IPparse;

public interface Message {

String bad_ip_file="IP地址库文件错误";

String unknown_country="未知国家";

String unknown_area="未知地区";

}

package com.showtime.IPparse;

public interface Message {

String bad_ip_file="IP地址库文件错误";

String unknown_country="未知国家";

String unknown_area="未知地区";

}

一个封装国家和地区的实体类

Java代码

package com.showtime.IPparse;

public class IPLocation {

private String country;

private String area;

public IPLocation() {

country = area = "";

}

public IPLocation getCopy() {

IPLocation ret = new IPLocation();

ret.country = country;

ret.area = area;

return ret;

}

public String getCountry() {

return country;

}

public void setCountry(String country) {

this.country = country;

}

public String getArea() {

return area;

}

public void setArea(String area) {

//如果为局域网,纯真IP地址库的地区会显示CZ88.NET,这里把它去掉

if(area.trim().equals("CZ88.NET")){

this.area="本机或本网络";

}else{

this.area = area;

}

}

}

package com.showtime.IPparse;

public class IPLocation {

private String country;

private String area;

public IPLocation() {

country = area = "";

}

public IPLocation getCopy() {

IPLocation ret = new IPLocation();

ret.country = country;

ret.area = area;

return ret;

}

public String getCountry() {

return country;

}

public void setCountry(String country) {

this.country = country;

}

public String getArea() {

return area;

}

public void setArea(String area) {

//如果为局域网,纯真IP地址库的地区会显示CZ88.NET,这里把它去掉

if(area.trim().equals("CZ88.NET")){

this.area="本机或本网络";

}else{

this.area = area;

}

}

}

一下是一个范围记录的类

Java代码

package com.showtime.IPparse;

public class IPEntry {

public String beginIp;

public String endIp;

public String country;

public String area;

public IPEntry() {

beginIp = endIp = country = area = "";

}

}

package com.showtime.IPparse;

public class IPEntry {

public String beginIp;

public String endIp;

public String country;

public String area;

public IPEntry() {

beginIp = endIp = country = area = "";

}

}

日志记录类

Java代码

package com.showtime.util;

import org.apache.log4j.Level;

import org.apache.log4j.Logger;

public class LogFactory {

private static final Logger logger;

static {

logger = Logger.getLogger("stdout");

logger.setLevel(Level.DEBUG);

}

public static void log(String info, Level level, Throwable ex)

{

logger.log(level, info, ex);

}

public static Level getLogLevel(){

return logger.getLevel();

}

}

package com.showtime.util;

import org.apache.log4j.Level;

import org.apache.log4j.Logger;

public class LogFactory {

private static final Logger logger;

static {

logger = Logger.getLogger("stdout");

logger.setLevel(Level.DEBUG);

}

public static void log(String info, Level level, Throwable ex)

{

logger.log(level, info, ex);

}

public static Level getLogLevel(){

return logger.getLevel();

}

}

下面是测试类

Java代码

package com.showtime.IPparse;

import junit.framework.TestCase;

public class IPtest extends TestCase {

public void testIp(){

//指定纯真数据库的文件名,所在文件夹

IPSeeker ip=new IPSeeker("QQWry.Dat","f:/qqwry");

//测试IP 58.20.43.13

System.out.println(ip.getIPLocation("58.20.43.13").getCountry()+":"+ip.getIPLocation("58.20.43.13").getArea());

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值