mmap
下面是一個很簡單、很一般的程式碼,內容是使用 openssl 所提供的函式去計算一個檔案的 MD5。既然這麼簡單為什麼要紀錄呢?理由有兩個:第一,紀錄一下要怎麼使用 openssl 的 library;第二是今天的重點,mmap。
一般來說,要計算一個檔案的 MD5,勢必要把整個檔案讀到記憶體當中(或是分批讀入,但勢必整個檔案都要吃進來),所以標準的程序應該是 open --> read --> md5 --> close。而在 read 這一步還需要額外準備一份記憶體空間給它。但如果使用 mmap 的話就可以直接少了 read 這一步了。
上面有顯示 mmap 的用法。要特別注意的用完以後一定要 munmap。
mmap() creates a new mapping in the virtual address space of the calling process. 其他的部份在使用時再問男人吧。
一般來說,要計算一個檔案的 MD5,勢必要把整個檔案讀到記憶體當中(或是分批讀入,但勢必整個檔案都要吃進來),所以標準的程序應該是 open --> read --> md5 --> close。而在 read 這一步還需要額外準備一份記憶體空間給它。但如果使用 mmap 的話就可以直接少了 read 這一步了。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <openssl/md5.h> long util_getFileSize( char * ); void util_md5File( char *, unsigned char * ); static long util_getFdSize( int ); int main( int argc, char *argv[] ) { int fileFd = 0; long fileSize = 0; unsigned char md5sum[MD5_DIGEST_LENGTH]; int i = 0; if( argc != 2 ) { printf( "Usage: md5 <file>\n" ); return 0; } fileSize = util_getFileSize( argv[1] ); if( fileSize == -1 ) { printf( "Error!\n" ); return 0; } util_md5File( argv[1], md5sum ); printf( "File Name: %s\n", argv[1] ); printf( "File Size: %lu\n", fileSize ); printf( "MD5:\n" ); for( i = 0 ; i < MD5_DIGEST_LENGTH; i++ ) { if( ( i % 4 ) == 0 ) { printf( "\t" ); } printf( "%02X ", md5sum[i] ); if( ( i % 4 ) == 3 ) { printf( "\n" ); } } return 0; } long util_getFileSize( char *_pFileName ) { int fd = open( _pFileName, O_RDONLY ); long fileSize = 0; if( fd < 0 ) { printf( "File open failed!\n" ); return -1; } fileSize = util_getFdSize( fd ); close( fd ); return fileSize; } void util_md5File( char *_pFileName, unsigned char *_pOutput ) { int fd = open( _pFileName, O_RDONLY ); long fileSize = 0; char *_pFile = NULL; if( fd < 0 ) { printf( "File open failed!\n" ); return; } fileSize = util_getFdSize( fd ); if( fileSize == -1 ) { return; } _pFile = mmap( 0, fileSize, PROT_READ, MAP_SHARED, fd, 0 ); MD5( ( unsigned char *)_pFile, fileSize, _pOutput ); munmap( _pFile, fileSize ); close( fd ); return; } static long util_getFdSize( int fd ) { struct stat statbuf; if( fstat( fd, &statbuf ) < 0 ) { close( fd ); return -1; } return statbuf.st_size; }
上面有顯示 mmap 的用法。要特別注意的用完以後一定要 munmap。
mmap() creates a new mapping in the virtual address space of the calling process. 其他的部份在使用時再問男人吧。
留言
張貼留言