GDAL的最大波段数限制及最大文件数限制

18 篇文章 0 订阅
6 篇文章 0 订阅

GDAL的最大波段数限制及最大文件数限制

最大波段数限制

GDAL写文件时,一个文件最多可以有多少个波段呢?

	int nMaxBandCount = atoi(CPLGetConfigOption("GDAL_MAX_BAND_COUNT", "65535"));
	printf("Max band count:%d\n", nMaxBandCount);

我们可以用CPLSetConfigOption来修改这个数值:

	//设置最大波段数
	CPLSetConfigOption("GDAL_MAX_BAND_COUNT", "65536");

那么这个数值最大能多大呢?

根据源码中的逻辑,在gcore\gdal_misc.cpp中,GDALCheckBandCount中进行波段数目检查:

int GDALCheckBandCount( int nBands, int bIsZeroAllowed )
{
   if (nBands < 0 || (!bIsZeroAllowed && nBands == 0) )
   {
       CPLError(CE_Failure, CPLE_AppDefined,
                "Invalid band count : %d", nBands);
       return FALSE;
   }
   const char* pszMaxBandCount = CPLGetConfigOption("GDAL_MAX_BAND_COUNT", "65536");
   /* coverity[tainted_data] */
   int nMaxBands = atoi(pszMaxBandCount);
   if ( nBands > nMaxBands )
   {
       CPLError(CE_Failure, CPLE_AppDefined,
                "Invalid band count : %d. Maximum allowed currently is %d. "
                "Define GDAL_MAX_BAND_COUNT to a higher level if it is a legitimate number.",
                nBands, nMaxBands);
       return FALSE;
   }
   return TRUE;
}

其中CPLGetConfigOption的定义如下:

const char * CPL_STDCALL
CPLGetConfigOption( const char *pszKey, const char *pszDefault )

{
#ifdef DEBUG_CONFIG_OPTIONS
    CPLAccessConfigOption(pszKey, TRUE);
#endif

    const char *pszResult = NULL;

    int bMemoryError = FALSE;
    char **papszTLConfigOptions = reinterpret_cast<char **>(
        CPLGetTLSEx(CTLS_CONFIGOPTIONS, &bMemoryError));
    if( papszTLConfigOptions != NULL )
        pszResult = CSLFetchNameValue(papszTLConfigOptions, pszKey);

    if( pszResult == NULL )
    {
        CPLMutexHolderD(&hConfigMutex);

        pszResult =
            CSLFetchNameValue(const_cast<char **>(g_papszConfigOptions), pszKey);
    }

    if( pszResult == NULL )
        pszResult = getenv(pszKey);

    if( pszResult == NULL )
        return pszDefault;

    return pszResult;
}

可以看到,源码中的逻辑是先从默认设置开始取值,如果没有,从环境变量中取值,否则返回默认值,并且这个值在源码中是一个int型的整数,所以其最大值就是int的最大值2147483647。
根据以上信息可知,除了用CPLSetConfigOption设置最大波段数外,还可以通过环境变量来设置,并且环境变量的优先级最高:
Linux下:
export GDAL_MAX_BAND_COUNT=2147483647

最大文件数量限制

在unix系统下,使用GDALOpen打开ENVI文件,会遇到打开文件数量511个后继续打开就会失败的问题。追查源码就会发现,这个问题的如下:

  gcore\gdaldataset.cpp    		GDALOpenEx  -->
  frmts\raw\envidataset.cpp		ENVIDataset::Open --> 
  port\cpl_vsil.cpp			VSIFOpenExL -->
  port\cpl_vsil_unix_stdio_64.cpp 	VSIUnixStdioFilesystemHandler::Open -->
  iofopen.c			fopen64

最后会发现,是系统的fopen64返回了NULL。系统底层的io函数为啥会返回null呢?
这是因为unix系统对于打开文件的句柄数量有限制,通过ulimit -a就可以看到最大文件数量限制,一般默认1024个,这就是为啥我们打开ENVI格式的文件,到511个就失败了。
ENVI的文件,会打开一个数据文件,同时打开一个头文件,一个文件占用两个fp,所以打开第512个时,读到头文件就1024个了,所以就打开失败了。
针对此问题,可以通过修改unix系统的最大文件数量来解决,不过最好的办法就是不要用GDALOpen缓存这么多的GDALDataset。

ubuntu临时修改文件数量的方法是:

  ulimit -SHn 1048576

ulimit 命令身分软限制和硬限制,硬限制就是实际的限制,而软限制是警告限制,它只会给出警告。
加-H就是硬限制,加-S就是软限制。默认显示的是软限制,如果运行ulimit 命令修改时没有加上-H或-S,就是两个参数一起改变。

永久生效的方法是修改文件: sudo vi /etc/security/limits.conf
添加

* soft nofile 65535   
* hard nofile 65535  

sudo echo "* soft nofile 65535"  >> /etc/security/limits.conf
sudo echo "* hard nofile 65535"  >> /etc/security/limits.conf

上面是一个进程打开文件数量的限制,除此以外,可能还存在系统总的限制,我看查看该限制:

cat /proc/sys/fs/file-max

可以临时修改这个限制:

sudo echo 26336040 > /proc/sys/fs/file-max

临时修改在机器重启后就会失效,要想永久生效,修改配置:

sudo vi /etc/sysctl.conf

加入

fs.file-max = 26336040
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深蓝静音

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值