我正在开发一个linux程序,该程序应该解析从另一台计算机或互联网下载的文件,并从该文件中收集信息。该程序还必须每隔n天/小时/分钟/任何时间按例程重新下载文件,并在文件发生更改时再次对其进行解析以保持更新。
但是,解析文件的过程可能需要大量资源。因此,我想要一个函数来检查文件自上次下载以来是否发生了更改。我想象这样的例子:
int get_checksum(char *filename) {
// New prototype, if no such function already exists in standard C-libraries
int result; // Or char/float/whatever
// ...
return result;
}
int main(void) {
char filename[] = { "foo.dat" };
char file_url[] = { "http://example.com/foo.dat" }
int old_checksum; // Or char/float/whatever
int new_checksum; // Or char/float/whatever
// ...
// Now assume that old_checksum has a value from before:
dl_file(filename, file_url); // Some prototype for downloading the file
if ((new_checksum = get_checksum(filename)) == -1) {
// Badness
}
else {
if (new_checksum != old_checksum) {
old_checksum = new_checksum;
// Parse the file
}
else {
// Do nothing
}
}
// ...
}
Q1:标准C/C++库中是否有get_checksum
这样的函数
Q2:如果不是:实现这一目标的最佳方式是什么
不需要:
-非常高级的功能
-加密或安全校验和
-将新文件与上一个旧文件进行比较的能力,因为新下载的文件将始终覆盖旧文件
您可以使用stat()
函数。它可以让您访问文件参数,如上次访问时间、上次修改时间、文件大小等:
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
但你需要对你将要使用的文件拥有执行权限。
手册页
在std::hash<>之前,C++语言中没有任何构建在C++11中,这非常简单,但可能适合您的需求。
上次我检查Boost(最常见的C++库扩展)中什么都没有。这里讨论了理由,但可能已经过时:
http://www.gamedev.net/topic/528553-why-doesnt-boost-have-a-cryptographic-hash-library/
所以,你最好的选择是:
std::hash和文件内容。
或者类似以下的东西可以保存到一个简单的标题中并链接:
http://www.zedwood.com/article/cpp-md5-function
或者你可以得到一个库,比如OpenSSL或Crypto++。
您可以进行XOR散列,在该散列中,您只对连续的无符号ints/long块进行异或运算,但这存在冲突问题。例如,如果文件大部分是字符,那么大多数字节都在普通ASCII/Unicode字符的范围内,因此会有很多未使用的密钥空间。
对于标准实现,您可以将文件读取为字符串,并使用C++11中的std::hash。http://en.cppreference.com/w/cpp/utility/hash
以下是第一种方法的示例:
unsigned int hash(vector<char> file){
unsigned int result;
int *arr = (int*)file.data();
for(int i = 0;i < file.size() / sizeof(unsigned int);i++)
result ^= arr[i];
return result;
}
你只需要把文件读入向量中。