主页 > imtoken钱包app下载链接 > 比特币源码--5--bitcoind(主要功能)数据目录及配置文件(四)
比特币源码--5--bitcoind(主要功能)数据目录及配置文件(四)
数据目录
这里的数据目录是比特币中的区块、区块链、交易、交易池、钱包、P2P网络等数据文件所在的目录。 该目录涉及到我们的比特币核心程序能否正常运行比特币代码文件是什么样子的,因此其正确设置至关重要。
try
{
.....
}
catch (const std::exception& e) {
PrintExceptionContinue(&e, "AppInit()");
} catch (...) {
PrintExceptionContinue(nullptr, "AppInit()");
}
即如果try中的代码出现异常,就会被catch捕获。 下面分析try中的代码。
if (!fs::is_directory(GetDataDir(false)))
{
fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str());
return false;
}
try
{
gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
} catch (const std::exception& e) {
fprintf(stderr,"Error reading configuration file: %s\n", e.what());
return false;
}
// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
try {
SelectParams(ChainNameFromCommandLine());
} catch (const std::exception& e) {
fprintf(stderr, "Error: %s\n", e.what());
return false;
}
我们先看第一行的if语句。 该语句判断GetDataDir(false)函数返回的数据路径是否为目录名。 如果不存在,则会打印指定目录不存在的错误信息,因为数据目录不正确。 ,比特币核心程序无法正常运行,因此返回false,程序退出。
if语句中fs的定义是:namespace fs = boost::filesystem。 文件系统库是一个可移植的文件系统操作库,可以跨平台操作目录、文件等。 文件系统库的所有内容都定义在 boost 命名空间的一个较低级别的命名空间中,称为 boost::filesytem。
boost::filesystem::path path("");//初始化
boost::filesystem::is_directory(file_path)//判断file_path是否为目录。
数据目录是否正确的关键在于GetDataDir(false)函数获取的目录信息是否正确。 接着我们看一下GetDataDir函数的具体实现。 这个函数的实现可以在 src/util.cpp 中找到。 (555行)
const fs::path &GetDataDir(bool fNetSpecific)
{
LOCK(csPathCached);
fs::path &path = fNetSpecific ? pathCachedNetSpecific : pathCached;
// This can be called during exceptions by LogPrintf(), so we cache the
// value so we don't have to do memory allocations after that.
if (!path.empty())
return path;
if (gArgs.IsArgSet("-datadir")) {
path = fs::system_complete(gArgs.GetArg("-datadir", ""));
if (!fs::is_directory(path)) {
path = "";
return path;
}
} else {
path = GetDefaultDataDir();
}
if (fNetSpecific)
path /= BaseParams().DataDir();
fs::create_directories(path);
return path;
}
该功能的实现流程图:
该功能详细解释如下:
1.根据fNetSpecific判断路径类型,是网络路径还是本地路径,如果为false,则可以称为本地路径。
2.路径不为空则直接返回。
3、如果参数中包含“-datadir”,获取参数路径信息:GetArg(“-datadir”, “”)比特币代码文件是什么样子的,否则获取默认数据路径。
4.判断是否为网络路径,如果是则获取Path中的BaseParams.DataDir()目录,定义在src/chainparamsbase.h中。 从false可以看出这段代码是不会执行的。
5. 最后创建数据目录并返回。
一般来说:
如果有路径路径,直接返回这条路径;
如果没有,检查参数gArgs中是否设置了路径。 如果设置正确(如果设置为网络目录,则会转换为本地路径),则在本地创建此路径并返回路径; 如果已设置但错误,则清除它的路径,返回一个空目录;
在 AppInit 函数中,
如果 (!fs::is_directory(GetDataDir(false)))
程序中传递给GetDataDir(false)函数的参数为false,即使用本地文件目录。 如果不设置“-datadir”参数,程序会执行流程图中的GetDefaultDataDir函数,该函数的实现也位于src/util。 cpp。 在这个函数中,我们可以获取Windows、Mac、Unix操作系统下比特币后台进程的默认数据目录。 详情如下:
fs::path GetDefaultDataDir()
{
// Windows < Vista: C:\Documents and Settings\Username\Application Data\Bitcoin
// Windows >= Vista: C:\Users\Username\AppData\Roaming\Bitcoin
// Mac: ~/Library/Application Support/Bitcoin
// Unix: ~/.bitcoin
#ifdef WIN32
// Windows
return GetSpecialFolderPath(CSIDL_APPDATA) / "Bitcoin";
#else
fs::path pathRet;
char* pszHome = getenv("HOME");
if (pszHome == nullptr || strlen(pszHome) == 0)
pathRet = fs::path("/");
else
pathRet = fs::path(pszHome);
#ifdef MAC_OSX
// Mac
return pathRet / "Library/Application Support/Bitcoin";
#else
// Unix
return pathRet / ".bitcoin";
#endif
#endif
}
pathCachedNetSpecific 和 pathCached 在 util.cpp 中定义:(584)
void ClearDatadirCache()
{
LOCK(csPathCached);
pathCached = fs::path();
pathCachedNetSpecific = fs::path();
}
path = fs::system_complete(gArgs.GetArg("-datadir", ""));
将路径转换为完整路径。 ://msdn.microsoft.com/en-us/library/hh874650(v=vs.120).aspx
path /= BaseParams().DataDir();
BaseParams 函数在 chainparamsbase.cpp 文件中定义。 (67)
const CBaseChainParams& BaseParams()
{
assert(globalChainBaseParams);
return *globalChainBaseParams;
}
返回的是*globalChainBaseParams,定义也在这个文件里,(65)
static std::unique_ptr globalChainBaseParams;
配置文件
数据目录创建完成后,程序将进入配置文件读取部分。
try
{
gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
} catch (const std::exception& e) {
fprintf(stderr,"Error reading configuration file: %s\n", e.what());
return false;
}
其中,BITCOIN_CONF_FILENAME定义在src/util.cpp中,其值为“bitcoin.conf”,表示配置文件。 (90)
const char * const BITCOIN_CONF_FILENAME = "bitcoin.conf";
ReadConfigFile 函数,顾名思义,读取配置文件。 在util.h文件中定义,具体实现在util.cpp中。 (601)
void ArgsManager::ReadConfigFile(const std::string& confPath)
GetArg函数首先判断其实现中是否有“-conf”参数。 如果存在,则使用ParseParmeters中参数解析结果中保存的参数值作为配置文件,否则使用默认的“bitcoin.conf”。
获取到配置文件名后,我们就可以分析ReadConfigFile函数的实现了。 该函数实现了对配置文件中参数和参数值的读取操作,并将读取到的参数信息存储到mapArgs和_mapMultiArgs中。
最后,为了防止在配置文件中设置数据目录参数datadir,通过ClearDatadirCache()函数将数据文件路径参数设置为空目录,这样下次进入GetDataDir()时,我们将基于新的数据目录创建一个数据目录。
分类:
技术要点:
相关文章: