oui.txt文件的格式化操作以及db文件的重写

Organizationally unique identifier (OUI) “组织唯一标识符”,是IEEE分发给各个厂家的唯一MAC标识符。

官方地址为:http://standards-oui.ieee.org/oui.txt

我们知道,设备的MAC地址由12位数字和字母混合组成,这里需要注意的是:MAC地址的前六位代表唯一的厂商,且MAC地址中的英文字符取值范围为A~F。

考虑这样一个需求,我们需要在自己的应用中查找某一个MAC对应的厂商,有两个方法可以实现:

直接把oui.txt下载到本地,然后将txt文件放到res文件夹下的raw文件夹下,然后在代码中直接查询,如下所示:

        InputStream inputStream = context.getResources().openRawResource(R.raw.oui);
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        BufferedReader reader = new BufferedReader(inputStreamReader);
        String line;
        try {
            while ((line = reader.readLine()) != null) {
                if (line.contains(mac)) {
                    return line;                    //获取到型号行
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

这样做的好处在于方便,坏处也显而易见:性能太低。

第二种方法是将oui.txt先格式化,然后将格式化的新的txt文件读取到数据库中,这样在应用中查询时将直接查询sqlite数据库,查询时间将大大缩短。

那么首先我们把oui.txt文件格式化,新的文件我们命名为new_oui.txt(需要注意的点已经写在代码注释中):

public class FileConvert {
    public static void main(String[] args){
        try{
            FileReader fr = new FileReader(new File("/Users/admin/Downloads/oui.txt"));
            BufferedReader br = new BufferedReader(fr);
            FileWriter fw = new FileWriter(new File("/Users/admin/Downloads/new_oui.txt"));
            String str;
            String tempStr;
            while ((str = br.readLine()) != null) {
                if(str.equals("") || str.length() < 7){
                    continue;
                }
                tempStr = str.substring(0,6);
                if(regexTest(tempStr)){//检查某一行的前六位是否是mac,如果是则进行抽取
                    str = tempStr + " " + str.substring(22);//从第22位字符开始的是厂商名字,将6位的mac和厂商名字拼接起来
                    fw.write(str + "\n");
                }
            }
            br.close();
            fr.close();
            fw.flush();
            fw.close();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public static boolean regexTest(String str){
        Pattern r = Pattern.compile("^[A-F0-9]{6}$");//mac的前六位由英文A~F及数字0-9构成
        Matcher m = r.matcher(str);
        return m.matches();
    }
}

经过这样一步操作后,我们得到了新的txt文件:

接下来要做的是从新的txt文件中读取数据到sqlite的db文件中:

首先把new_oui.txt放到raw文件夹下,然后把它读取到应用在本机中的本地文件夹下:

public static void writeFile(){
        try {
            if(!(new File("/data/data/xxx.xxx.xx/new_oui.txt").exists())){
                InputStream is = MyApplication.getContext().getResources().openRawResource(
                        R.raw.new_oui);
                FileOutputStream fos = new FileOutputStream("/data/data/xxx.xxx.xx/new_oui.txt");
                byte[] buffer = new byte[400000];
                int count;
                while ((count = is.read(buffer)) > 0) {
                    fos.write(buffer, 0, count);
                }
                fos.close();
                is.close();
            }

        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

然后,我们开始把new_oui.txt中的数据导入到db文件中,这里为了方便,我并没有构造一个新的db文件,而是从网上下载了一个db文件,然后将其进行重写:

public static void rewriteDb(){
        deleteAll();
        try{
            FileReader fr = new FileReader(new File("/data/data/xxx.xx.xxx/new_oui.txt"));
            BufferedReader br = new BufferedReader(fr);
            String str;
            String mac;
            String factory;
            while ((str = br.readLine()) != null) {
                if(str.equals("") || str.length() < 7){
                    continue;
                }
                mac = str.substring(0,6);
                factory = str.substring(7,str.length());
                DeviceFactoryEntity entity = new DeviceFactoryEntity();
                entity.threeByteMac = mac;
                entity.factory = factory;
                insert(entity);
            }
            br.close();
            fr.close();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

public static void deleteAll(){
        try {
            String sqlDeleteData = "DELETE  FROM device_factory_entity";
            getInstance().db.execSQL(sqlDeleteData);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

public static void insert(DeviceFactoryEntity entity){
        if(entity != null){
            ContentValues values = new ContentValues();
            values.put("three_byte_mac",entity.threeByteMac);
            values.put("factory",entity.factory);
            getInstance().db.insert("device_factory_entity",null,values);
        }
    }

完成以后,就可以愉快的用sqlite去查询MAC对应的厂商名啦。

这里给出一个db文件的下载,db文件中的数据对应2018年9月底的oui.txt:

https://download.csdn.net/download/vaneasley/10715610

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值