为何要自己写配置文件
1 解决引入很多库的问题
2 解决流程问题而非语言问题
3 学会简化问题
读写配置文件的知识
一下是一个txt配置文件,注意文件格式,如果我们在utf8 文件下读写,分为两种,一种是utf8 带BOM,一种不带,我们都要考虑
#id(int):address(varchar):width(int):height(int)
#418511899@qq.com author:钱波 qianbo 2021-02-28
//camera
//tcp or udp
1 rtsp://127.0.0.1/qianbo2.264 1280 720 live/1001
#2 rtsp://127.0.0.1/out.264 1280 720 live/1001
#2 rtsp://127.0.0.1/1.264 640 360 live/1002
ok,# 和//都是注释,如果加上这个符号,就必须要把这一行忽略
读出一行,标准的c++非常方便,一句话就出来,用java使用readLine函数
std::getline(infile, temp);
注意在linux下和windows下是不一样的,linux下读出来的会有一个’\r’,所以要去除
static void trim(std::string &s)
{
if (s.empty())
return;
s.erase(s.find_last_not_of('\r') + 1); //the linux system getline must remove the '\r'
s.erase(s.find_last_not_of(' ') + 1);
//s.erase(s.find_last_not_of('\t') + 1);
s.erase(0, s.find_first_not_of(' '));
//s.erase(0, s.find_first_not_of('\t'));
}
这是语言无关的,如果是是用c,c++,问题都是一样,需要了解系统和知识。接下来这个问题是也会经常碰到的,就是带BOM头部的utf8文件,要做产品,就必须把各种情况测试到,并且解决掉这个问题。
if (temp.length() > 3 /*0xEF 0xBB 0xBF*/)
{
uint8_t *pos = (uint8_t*)temp.c_str();
if (*pos == 0xEF)
{
temp = temp.substr(3);//去除前三字节
printf("%02x %02x %02x \n", *(pos), *(pos + 1), *(pos + 2));
cout << "utf8 and BOM" << endl;
}
}
使用java读写文件,并跳过注释,会少一些问题
public void readFile(String filename ) throws IOException {
FileInputStream fis=new FileInputStream(filename);
InputStreamReader isr=new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(isr);
String line="";
String[] arrs=null;
while ((line=br.readLine())!=null) {
String str = line.trim()//去除前后空格
if(str[0] == '#' || (str[0]=='/' && str[1] == '/')
continue;
arrs=line.split(" ");
//准备一个结构放入,parseInt这里自己准备异常抛出
int id = Integer.parseInt(arrs[0]);
String address = arrs[1];
int width = Integer.parseInt(arrs[2]);
int height = Integer.parseInt(arrs[3]);
String live = arrs[4];
System.out.println(id + " " + address + " " + width + " "+height + " " +live);
}
br.close();
isr.close();
fis.close();
}
nodejs读写文件也是非常方便的,不用那么复杂,split 等函数和java等等都一致,总的来讲,还是软件工程的问题。
var fs = require('fs')
fs.readFile('in.txt', function (error, data) {
if (error) {
console.log('error occur')
} else {
var str = data.toString();
var test = str.split("\r\n");
console.log(test.length);
for (let i = 0; i < test.length; i++) {
let x = test[i];
if (x[0] == '#' || (x[0] == '/' && x[1] == '/')) {
console.log("not use");
}
else{
//这里在继续split
console.log(x);
}
}
}
})
nodejs打印出的结果,不使用则打印not use,使用则打印该行,结果:
几种语言流程等都一样,但是c++需要的是去除\r(linux下),也需要去除BOM头部,如果是有BOM头部的文件。因为c++与c稍底层,没有像java node 等封装那么多,但同时也提供了很强的灵活性和运行效率。
总结:简化问题
ok,如果判别是注释的,首先我们简化问题,我们的注释只出现在首字节,就好办了,我们确实要学会简化问题,否则一个读写文件就是一个很大的问题,花费很长的时间是不值得的,因为是我们自己在用,做法就是
1 去除前后空格
2 判断第一个字符为‘#’ 或者第一第二个字符都为‘/’
3 条件满足,跳过这一行,不做解析
4 split 分割我们的配置,注意异常处理 放入结构体