TIFF文件解析

TIFF文件解析TIF 文件是一种标签标记文件 为什么这么说呢 它的文件的构成方式就是根据 Tag 来标记的 同时还可以记录地理信息 坐标 投影等信息 非常方便在 GIS 领域使用 网上关于 TIFF 文件的介绍也是不少 今天我主要是把我之前使用 C 解析 TIF 文件的过程记录下来 1 定义 TIFF 文件的结构体 TIFF 文件的数据结构 typedefstruc FILE pfile

//TIFF文件的数据结构 typedef struct { FILE* pfile; //tiff文件 TIFF_UINT16_T tiff_byte_order; //字节序  TIFF_UINT16_T tiff_version; //文件版本 TIFF_UINT32_T tiff_dir_off; //DE位置 long tif_width; //宽度 long tif_height; //高度 long compression; //压缩 1:不压缩 long photo_metric_inter; //图像的色彩模式 2:RGB 3:索引图片 long bit_per_samples ; //像素的分量值 long samples_per_pixel; //每个象素的通道数 long rows_per_strip; //每个扫描行的图像数据行数 long bcount_strip_offset; //多少条扫描行 long planar_config; //图像数据存储方式 1 - RGBRGBRGB 2 - RRRGGGBBB TIFF_UINT32_T* strip_line; //扫描行的起始位置 long bcount_strip_byte_counts; // TIFF_UINT32_T* strip_byte_counts;//每条扫描行的字节数目 TIFF_UINT16_T* color_map; //颜色表 Tile tile; //瓦片数据 GeoTiff geo_tiff; //GeoTiff文件头 }TiffFile;

2.定义在这个过程中使用到的宏

#define TIFF void* #define TIFF_VERSION_CLASSIC 42 #define TIFF_BIGENDIAN 0x4d4d #define TIFF_LITTLEENDIAN 0x4949 #define PI 3. #define SIZEOF_INT 4 /* Signed 8-bit type */ #define TIFF_INT8_T signed char /* Unsigned 8-bit type */ #define TIFF_UINT8_T unsigned char /* Signed 16-bit type */ #define TIFF_INT16_T signed short /* Unsigned 16-bit type */ #define TIFF_UINT16_T unsigned short /* Signed 32-bit type formatter */ #define TIFF_INT32_FORMAT "%d" /* Signed 32-bit type */ #define TIFF_INT32_T signed int /* Unsigned 32-bit type */ #define TIFF_UINT32_T unsigned int /* Signed 64-bit type */ #define TIFF_INT64_T signed __int64 /* Unsigned 64-bit type formatter */ #define TIFF_UINT64_FORMAT "%I64u" /* Unsigned 64-bit type */ #define TIFF_UINT64_T unsigned __int64 /* Signed size type */ #if defined(_WIN64) #define TIFF_SSIZE_T signed __int64 #else #define TIFF_SSIZE_T signed int #endif /* Signed size type formatter */ #if defined(_WIN64) #define TIFF_SSIZE_FORMAT "%I64d" #else #define TIFF_SSIZE_FORMAT "%ld" #endif /* Pointer difference type */ #define TIFF_PTRDIFF_T long #define TIFF_ERROR_PATH_SUCCESS 0  #define TIFF_ERROR_PATH_NULL -1 #define TIFF_ERROR_OPEN_FAILED -2 #define TIFF_ERROR_BYTE_ORDER -3 #define TIFF_ERROR_TIFF_VER -4

如果里面使用到地理信息还会使用到以下定义:

#define TIFF_GEO_GeoTagPixelScale 33550 #define TIFF_GEO_GeoTagTiePoint 33922 #define TIFF_GEO_GeoTagTransMatrix 34264 #define TIFF_GEO_GeoTagDirectory 34735 #define TIFF_GEO_GeoTagDoubleParams 34736 #define TIFF_GEO_GeoTagASCIIParams 34737

3.首先打开TIFF文件

int tif_open( const char* tiff_path , TiffFile* tf) { if ( tiff_path == NULL) { return -1; } //打开文件 FILE* ptiff = fopen( tiff_path , "rb" ); if ( ptiff == NULL ) { return -2; } tf->pfile = ptiff; fseek( ptiff ,0 ,SEEK_CUR ); //得到字节序 TIFF_UINT16_T byte_order; fread( &byte_order,1 , 2,ptiff ); tf->tiff_byte_order = byte_order; if ( !((byte_order ==TIFF_BIGENDIAN) || (byte_order ==TIFF_LITTLEENDIAN)) ) { fclose( ptiff ); return -3; } TIFF_UINT8_T s[2]={ 
  0}; //得到TIFF版本 fread( s ,2 , 1, ptiff ); TIFF_INT16_T byte_ver = sget2(s,byte_order); tf->tiff_version = byte_ver; if ( TIFF_VERSION_CLASSIC !=byte_ver ) { fclose( ptiff ); return -4; } //得到IFD的文件偏移量 TIFF_UINT32_T IFDoffset = get4( ptiff , byte_order ); tf->tiff_dir_off = IFDoffset; fseek( ptiff , IFDoffset-8 ,SEEK_CUR ); //得到IFD的数量 TIFF_UINT16_T IFDnum = get2( ptiff , byte_order ); int fs = fseek( ptiff ,2+IFDoffset , SEEK_SET ); TIFF_UINT16_T tdir_tag = 0 , tdir_type = 0 ; TIFF_UINT32_T tdir_count = 0 , toff_long = 0 ; for (TIFF_UINT16_T i=0x0000;i< IFDnum ;i++) { TIFF_UINT32_T file_offset = 2+IFDoffset+12*i; int fs = fseek( ptiff , 2+IFDoffset+12*i , SEEK_SET ); tdir_tag = get2( ptiff , byte_order ); if ( tdir_tag == 0x100 )//width { tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); if ( ( tdir_type == 3 || tdir_type == 4 ) && byte_order == 0x4d4d/*Motor*/ && tdir_count == 1 ) { toff_long = (TIFF_UINT32_T)get2( ptiff , byte_order ); } else { toff_long = get4( ptiff , byte_order ); } tf ->tif_width = toff_long ; continue; } else if ( tdir_tag == 0x101 )//height { tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); if ( ( tdir_type == 3 || tdir_type == 4 ) && byte_order == 0x4d4d/*Motor*/ && tdir_count == 1 ) { toff_long = (TIFF_UINT32_T)get2( ptiff , byte_order ); } else { toff_long = get4( ptiff , byte_order ); } tf ->tif_height = toff_long ; continue; } else if ( tdir_tag == 0x102 )//BitsPerSample { tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); if ( tdir_count == 1 ) { if ( ( tdir_type == 3 || tdir_type == 4 ) && byte_order == 0x4d4d/*Motor*/ && tdir_count == 1 ) { toff_long = (TIFF_UINT32_T)get2( ptiff , byte_order ); } else { toff_long = get4( ptiff , byte_order ); } tf -> bit_per_samples = toff_long ; } else { toff_long = get4( ptiff , byte_order ); TIFF_UINT16_T* sl = (TIFF_UINT16_T*)get_byte_mem( ptiff , toff_long , tdir_count*sizeof(TIFF_UINT16_T) ); TIFF_UINT16_T* s2 = sl; for ( int i = 0 ; i < (int)tdir_count ; i++ ) { TIFF_UINT32_T s16 = sget2((TIFF_UINT8_T*)(s2 + i) , tf->tiff_byte_order ); tf -> bit_per_samples += s16 ; } } continue; } else if ( tdir_tag == 0x103 )//Compression { tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); if ( ( tdir_type == 3 || tdir_type == 4 ) && byte_order == 0x4d4d/*Motor*/ && tdir_count == 1 ) { toff_long = (TIFF_UINT32_T)get2( ptiff , byte_order ); } else { toff_long = get4( ptiff , byte_order ); } tf ->compression = toff_long ; continue; } else if ( tdir_tag == 0x106 )//PhotometricInterpretation { tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); if ( ( tdir_type == 3 || tdir_type == 4 ) && byte_order == 0x4d4d/*Motor*/ && tdir_count == 1 ) { toff_long = (TIFF_UINT32_T)get2( ptiff , byte_order ); } else { toff_long = get4( ptiff , byte_order ); } tf ->photo_metric_inter = toff_long ; continue; } else if ( tdir_tag == 0x111 )//StripOffsets { tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); toff_long = get4( ptiff , byte_order ); tf ->bcount_strip_offset = tdir_count ; if ( tdir_count > 1 ) { TIFF_UINT32_T* sl = (TIFF_UINT32_T*)get_byte_mem( ptiff , toff_long , tdir_count * sizeof(TIFF_UINT32_T) ); TIFF_UINT32_T* sl2 = sl; //字节序的转换 for ( int i = 0 ; i < (int)tdir_count ; i++ ) { TIFF_UINT32_T s32 = sget4((TIFF_UINT8_T*)sl2 , tf->tiff_byte_order ); memcpy( sl2 , &s32 , 4 ); sl2+=1; } tf ->strip_line = sl ; } else { tf ->bcount_strip_offset = 1; tf ->strip_line = new TIFF_UINT32_T; *(tf ->strip_line) = toff_long; } continue; } else if ( tdir_tag == 0x115 )//SamplesPerPixel { tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); if ( ( tdir_type == 3 || tdir_type == 4 ) && byte_order == 0x4d4d/*Motor*/ && tdir_count == 1 ) { toff_long = (TIFF_UINT32_T)get2( ptiff , byte_order ); } else { toff_long = get4( ptiff , byte_order ); } tf ->samples_per_pixel = toff_long ; continue; } else if ( tdir_tag == 0x116 )//RowsPerStrip { tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); if ( ( tdir_type == 3 || tdir_type == 4 ) && byte_order == 0x4d4d/*Motor*/ && tdir_count == 1 ) { toff_long = (TIFF_UINT32_T)get2( ptiff , byte_order ); } else { toff_long = get4( ptiff , byte_order ); } tf ->rows_per_strip = toff_long; continue; } else if ( tdir_tag == 0x117 )//StripByteCounts { tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); toff_long = get4( ptiff , byte_order ); tf ->bcount_strip_byte_counts = tdir_count ; if ( tf ->bcount_strip_byte_counts > 1 ) { TIFF_UINT32_T* sl = (TIFF_UINT32_T*)get_byte_mem( ptiff , toff_long , tdir_count*sizeof(TIFF_UINT32_T) ); TIFF_UINT32_T* sl2 = sl; //字节序的转换 for ( int i = 0 ; i < (int)tdir_count ; i++ ) { TIFF_UINT32_T s32 = sget4((TIFF_UINT8_T*)sl2 , tf->tiff_byte_order ); memcpy( sl2 , &s32 , 4 ); sl2+=1; } tf ->strip_byte_counts = sl ; } else { tf ->bcount_strip_byte_counts = 1; tf ->strip_byte_counts = new TIFF_UINT32_T; *(tf ->strip_byte_counts) = toff_long; } continue; } else if ( tdir_tag == 0x11c )//Planar Configuration { tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); if ( ( tdir_type == 3 || tdir_type == 4 ) && byte_order == 0x4d4d/*Motor*/ && tdir_count == 1 ) { toff_long = (TIFF_UINT32_T)get2( ptiff , byte_order ); } else { toff_long = get4( ptiff , byte_order ); } tf->planar_config = toff_long ; continue; } else if ( tdir_tag== 0x140 )//Color map { tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); toff_long = get4( ptiff , byte_order ); int pow1 = 0; if ( tf ->bit_per_samples == 1 ) { pow1 = 1<<1; } else if ( tf ->bit_per_samples == 4 ) { pow1 = 1<<4; } else if ( tf ->bit_per_samples == 8 ) { pow1 = 1<<8; } tf ->color_map = (TIFF_UINT16_T*)get_byte_mem( ptiff , toff_long , 3*pow1*2 ); } else if ( tdir_tag== 0x142 )//tile width { tf ->tile.is_tile = true ; tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); toff_long = get4( ptiff , byte_order ); tf ->tile.tile_width = toff_long ; continue; } else if ( tdir_tag== 0x143 )//tile height { tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); toff_long = get4( ptiff , byte_order ); tf ->tile.tile_height = toff_long ; continue; } else if ( tdir_tag== 0x144 )//tile offset { tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); toff_long = get4( ptiff , byte_order ); tf ->tile.tile_offset_count = tdir_count ; if ( tdir_count > 1 ) { tf ->tile.tile_offset_list = (TIFF_UINT32_T*)get_byte_mem( ptiff , toff_long , tdir_count*sizeof(TIFF_UINT32_T) ); } continue; } else if ( tdir_tag== 0x145 )//tile byte count { tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); toff_long = get4( ptiff , byte_order ); tf ->tile.tile_byte_num_count = tdir_count ; if ( tdir_count > 1 ) { tf ->tile.tile_byte_num_list = (TIFF_UINT32_T*)get_byte_mem( ptiff , toff_long , tdir_count*sizeof(TIFF_UINT32_T) ); } continue; } else if ( tdir_tag == 33550 ) //ModelPixelScaleTag { tf -> geo_tiff.is_geotiff = true ; tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); toff_long = get4( ptiff , byte_order ); if ( tdir_count == 3 && tdir_type == 12 ) { TIFF_UINT8_T* ps = (TIFF_UINT8_T*)get_byte_mem( ptiff , toff_long , tdir_count*8*sizeof(TIFF_UINT8_T) ); tf -> geo_tiff.pixel_scale.scaleX = long_to_double( sget8( ps , byte_order)) ; tf -> geo_tiff.pixel_scale.scaleY = long_to_double( sget8( ps + 8 , byte_order)) ; tf -> geo_tiff.pixel_scale.scaleZ = long_to_double( sget8( ps + 16 , byte_order)) ; delete[] ps; ps = NULL; } continue; } else if ( tdir_tag == 33922 ) //ModelTiePointTag { tf -> geo_tiff.is_geotiff = true ; tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); toff_long = get4( ptiff , byte_order ); if ( tdir_type == 12 && tdir_count >= 6 ) { TIFF_UINT8_T* ps = (TIFF_UINT8_T*)get_byte_mem( ptiff , toff_long , tdir_count*8*sizeof(TIFF_UINT8_T) ); tf -> geo_tiff.tie_point.SrcX = long_to_double( sget8( ps , byte_order)) ; tf -> geo_tiff.tie_point.SrcY = long_to_double( sget8( ps +8 , byte_order)) ; tf -> geo_tiff.tie_point.SrcZ = long_to_double( sget8( ps + 16 , byte_order)) ; tf -> geo_tiff.tie_point.DecX = long_to_double( sget8( ps + 24, byte_order)) ; tf -> geo_tiff.tie_point.DecY = long_to_double( sget8( ps + 32 , byte_order)) ; tf -> geo_tiff.tie_point.DecZ = long_to_double( sget8( ps + 40 , byte_order)) ; delete[] ps; ps = NULL; } continue; } else if ( tdir_tag == 34735 ) //GeoKeyDirectoryTag { tf -> geo_tiff.is_geotiff = true ; tf -> geo_tiff.is_geokeys = true ; tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); toff_long = get4( ptiff , byte_order ); tf -> geo_tiff.geo_tag_directory = (TIFF_UINT16_T*)get_byte_mem( ptiff , toff_long , tdir_count*sizeof(TIFF_UINT16_T) ); continue; } else if ( tdir_tag == 34736 ) //GeoDoubleParamsTag { tf -> geo_tiff.is_geotiff = true ; tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); toff_long = get4( ptiff , byte_order ); tf -> geo_tiff.double_param_count = tdir_count ; tf -> geo_tiff.geo_double = (double*)get_byte_mem( ptiff , toff_long , tdir_count*sizeof(double) ); continue; } else if ( tdir_tag == 34737 ) //GeoAsciiParamsTag { tf -> geo_tiff.is_geotiff = true ; tdir_type = get2( ptiff , byte_order ); tdir_count = get4( ptiff , byte_order ); toff_long = get4( ptiff , byte_order ); tf -> geo_tiff.ascii_param_count = tdir_count ; tf -> geo_tiff.geo_ascii = (char*)get_byte_mem( ptiff , toff_long , tdir_count*sizeof(char) ); break; } } return 0; }
int read_tiff_file( int view_w ,int view_h , double sca , TiffFile* tiff_file , TIFF_UINT8_T* pbuf ) { double sc = 1 / sca ;//目标文件相对于源文件放大的倍数 FILE *pfile = tiff_file->pfile; int samples_per_pixel = tiff_file->samples_per_pixel; TIFF_UINT32_T* line_start = tiff_file->strip_line ; int SrcWidth = tiff_file->tif_width; for ( int i = view_h-1; i >=0 ; i-- )//上下颠倒 { //选取最邻近的点 int tSrcH = (int)( sc * i + 0.5); for ( int j = 0; j < view_w; j++) { int tSrcW = (int)( sc * j + 0.5); fseek ( pfile , line_start[tSrcH] + tSrcW * samples_per_pixel , SEEK_SET ); fread( pbuf ,samples_per_pixel ,1 , pfile ); TIFF_UINT8_T u; u = pbuf[0]; //// pbuf[0] = pbuf[2]; // BGR -> RGB // pbuf[2] = u; //// pbuf += 4/*samples_per_pixel*/; } } return 0; }

读取块状数据:

int read_tile_tiff_file( int view_w ,int view_h , double sca , TiffFile* tiff_file , TIFF_UINT8_T* pbuf ) { FILE *pfile = tiff_file->pfile; int samples_per_pixel = tiff_file->samples_per_pixel; TIFF_UINT32_T* line_start = tiff_file->strip_line ; int SrcWidth = tiff_file->tif_width; double sc = 1 / sca ;//目标文件相对于源文件放大的倍数 TIFF_UINT32_T*tile_offset = tiff_file->tile.tile_offset_list; //偏移量列表 int pos_h = 0 ,pos_w = 0; int table_w = (int)( tiff_file->tif_width/ tiff_file->tile.tile_width); if ( tiff_file->tif_width% tiff_file->tile.tile_width > 0 ) { table_w ++ ; } int table_h = (int)( tiff_file->tif_height/ tiff_file->tile.tile_height)+1; if ( tiff_file->tif_height% tiff_file->tile.tile_height > 0 ) { table_h ++ ; } int tile_H = tiff_file->tile.tile_height ; int tile_W = tiff_file->tile.tile_width ; //for ( int i = 0 ; i< desH ; i ++ ) for ( int i = view_h-1 ; i >= 0 ; i -- ) { int tSrcH = (int)( sc * i + 0.5); pos_h = tSrcH / tile_H; for ( int j = 0 ; j < view_w ; j ++ ) { int tSrcW = (int)( sc * j + 0.5); pos_w = tSrcW / tile_W; TIFF_UINT32_T file_offset_start = tile_offset[ pos_h*table_w + pos_w ]; to_client( tSrcW , tSrcH , tile_W , tile_H ); fseek ( pfile , file_offset_start+(tSrcH*tile_W+ tSrcW)*samples_per_pixel, SEEK_SET ); fread( pbuf ,samples_per_pixel ,1 , pfile ); TIFF_UINT8_T u; u = pbuf[0]; //// pbuf[0] = pbuf[2]; // BGR -> RGB // pbuf[2] = u; //// pbuf += 4/*samples_per_pixel*/; } } return 0; }

5.如果TIFF中包含地理信息,还需要把地理信息取出来

//通过像素坐标的范围确定地理坐标的范围 void geo_coord( TiffFile* tf , geoRECT pixel_rect , geoRECT&geoRect ) { geoRect.left = tf->geo_tiff.tie_point.DecX + ( pixel_rect.left - tf->geo_tiff.tie_point.SrcX ) * tf->geo_tiff.pixel_scale.scaleX ; geoRect.top = tf->geo_tiff.tie_point.DecY + ( pixel_rect.top - tf->geo_tiff.tie_point.SrcY ) * tf->geo_tiff.pixel_scale.scaleY ; geoRect.right = tf->geo_tiff.tie_point.DecX + ( pixel_rect.right - tf->geo_tiff.tie_point.SrcX ) * tf->geo_tiff.pixel_scale.scaleX ; geoRect.botton = tf->geo_tiff.tie_point.DecY - ( pixel_rect.botton - tf->geo_tiff.tie_point.SrcY ) * tf->geo_tiff.pixel_scale.scaleY ; }

6.最后,如果是Google投影,则不需要proj4来转换,直接使用以下函数就可以实现地理坐标新(WGS84)和Google投影之间的坐标转换

#define PI 3. void web_mercator_2_lonlat( coordPairs&ml ) { ml.x = ml.x / . * 180; double y = ml.y / . * 180; ml.y = 180 / PI * ( 2 * atan ( exp ( y * PI / 180 ) ) - PI / 2 ); } void lonlat_2_web_mercator( coordPairs&ml ) { ml.x = ml.x * . / 180; double y = log ( tan ( ( 90 + ml.y ) * PI / 360 ) ) / ( PI / 180 ); ml.y = y * . / 180; }
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/201864.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午8:26
下一篇 2026年3月20日 上午8:26


相关推荐

  • 动态网页爬虫

    动态网页爬虫网页加载数据的另一种方式——通过API(ApplicationProgrammingInterface,应用程序编程接口)加载数据网页通过API获取数据,实时更新内容,它规定了网页与服务

    2022年7月1日
    28
  • C++面试题汇总 (一)

    C++面试题汇总 (一)C 面试题汇总 一 一 基础题二 算法题一 基础题 new delete malloc free 关系 delete 会调用对象的析构函数 和 new 对应 free 只会释放内存 new 调用构造函数 malloc 与 free 是 C C 语言的标准库函数 new delete 是 C 的运算符 它们都可用于申请动态内存和释放内存 对于非内部数据类型的对象而言 光用 maloc free 无法满足动态对象的要

    2026年3月18日
    1
  • ROS与科大讯飞语音库集成:实现语音控制机器人小车

    ROS与科大讯飞语音库集成:实现语音控制机器人小车

    2026年3月14日
    3
  • 剑指 Offer 56 – II. 数组中数字出现的次数 II

    剑指 Offer 56 – II. 数组中数字出现的次数 II在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。示例 1:输入:nums = [3,4,3,3]输出:4示例 2:输入:nums = [9,1,7,9,7,9,7]输出:1限制:1 <= nums.length <= 100001 <= nums[i] < 2^31设置一个数组代表32位,每一位代表当前所有数组中当前位出现次数之和。然后%3,然后拼凑class Solution {public: in

    2022年8月8日
    8
  • centos8安装rabbitmq_rabbitmq镜像集群

    centos8安装rabbitmq_rabbitmq镜像集群rabbitmq集群搭建1分别在3台节点安装rabbitmq-server在3台虚拟机(10.0.11.5410.0.11.5610.0.11.57)分别安装相同版本的rabbitmq-server及erlang,2分别修改三台节点的/etc/hosts文件注意必须修改主机名hostnamectlset-hostnamenode1#node2,3以此类推每台节点hosts文件修改后如下3将三台节点的.erlang.cookie内容修改一致(不一致创建集群会报错

    2025年10月24日
    4
  • SpringBoot源码解析之注解

    SpringBoot源码解析之注解本文的代码基于1.5.9版本启动类中都需要添加@SpringBootApplication注解,该注解中包含了三个重要注解:1、@SpringBootConfiguration标记为springBoot应用,在这个注解中又有@Configuration表示是个注解配置。2、@EnableAutoConfiguration该注解中又包含@AutoConfigurationPackage…

    2022年6月3日
    79

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号