Perforce P4 .NET API GetFileMetaData() 返回 NullReferenceException
我运行了从 P4 下载的 P4api.net 示例 C# 代码,以遍历我拥有的本地 P4 /depot
存储库。当示例代码尝试读取 //depot/subdirA
中的子目录和文件时,对 API 函数 GetFileMetaData()
的调用会遇到空指针异常。当 //depot/subdirA
只有子目录且其中没有文件时,会发生这种情况。如果 //depot/subdirA
有一个或多个文件,则 GetFileMetaData()
可以正常工作。我一定错过了一些东西,因为我假设 GetFileMetaData()
应该适用于存在或不存在文件的目录。
以下是 P4 示例代码 - 请参阅代码注释以了解异常位置:
// if we have the depot path, get a list of the subdirectories from the depot
if (!String.IsNullOrEmpty(depotPath))
{
IList<string> subdirs = _repository.GetDepotDirs(null, String.Format("{0}/*", depotPath));
if ((subdirs != null) && (subdirs.Count >0))
{
subdirectories = P4DirectoryMap.FromDirsOutput(_repository, Workspace, this, subdirs);
foreach (P4Directory dir in subdirectories.Values)
{
dir.InDepot = true;
}
}
IList<FileMetaData> fileList = _repository.GetFileMetaData(null, FileSpec.DepotSpec(String.Format("{0}/*", depotPath)));
// get a list of the files in the directory - debugger hit Null Exception within this call.
if (fileList != null)
{
files = P4FileMap.FromFstatOutput(fileList);
// if the directory contains files from the depot, we can use
// the local path of one of those files to determine the local
// path for this directory
if ((String.IsNullOrEmpty(localPath)) && (files != null) && (files.Count > 0))
{
我下载了 P4api.net API 源代码,并在 GetFileMetaData()
中观察到 r.TaggedOutput == null 当主题目录中不包含文件,只有更多子目录时。这可能是我对源代码的误解,但我认为代码应该在运行 FOR 循环之前检查
r.TaggedOutput == null
,请参阅代码注释以了解异常位置:
public IList<FileMetaData> GetFileMetaData(Options options, params FileSpec[] filespecs )
{
P4.P4Command fstatCmd = new P4.P4Command(_connection._p4server, "fstat", true, FileSpec.ToStrings(filespecs));
P4.P4CommandResult r = fstatCmd.Run(options);
if (r.Success != true)
{
P4Exception.Throw(r.ErrorList);
return null;
}
List<FileMetaData> value = new List<FileMetaData>();
foreach (P4.TaggedObject obj in r.TaggedOutput)
// Null Exception was caused by r.TaggedOutput=null when the sub dir has no file.
{
FileMetaData fmd = new FileMetaData();
fmd.FromFstatCmdTaggedData(obj);
value.Add(fmd);
}
return value;
}
我如何解决这个问题,因为人们可以期望仓库目录包含目录或文件或两者,但 GetFileMetaData() 似乎期望目录中始终包含文件?我是否必须为传入的“选项”参数指定一个可以防止此异常的选项?或者是否有另一个 API 调用来检查目录中是否存在文件,代码可以在调用 GetFileMetaData()
之前调用该文件?
I ran a P4api.net sample C# code downloaded from P4 to traverse a local P4 /depot
repository that I have. When the sample code attempts to read the //depot/subdirA
for sub directories and files, the call to API function GetFileMetaData()
hits a null pointer exception. This happens when //depot/subdirA
has only sub directories with no file in it. If //depot/subdirA
has one or more files then GetFileMetaData()
works properly. I must be missing something as I assume that GetFileMetaData()
should work for directory with or without files existing.
Following is the P4 sample code - please see code comment for exception location:
// if we have the depot path, get a list of the subdirectories from the depot
if (!String.IsNullOrEmpty(depotPath))
{
IList<string> subdirs = _repository.GetDepotDirs(null, String.Format("{0}/*", depotPath));
if ((subdirs != null) && (subdirs.Count >0))
{
subdirectories = P4DirectoryMap.FromDirsOutput(_repository, Workspace, this, subdirs);
foreach (P4Directory dir in subdirectories.Values)
{
dir.InDepot = true;
}
}
IList<FileMetaData> fileList = _repository.GetFileMetaData(null, FileSpec.DepotSpec(String.Format("{0}/*", depotPath)));
// get a list of the files in the directory - debugger hit Null Exception within this call.
if (fileList != null)
{
files = P4FileMap.FromFstatOutput(fileList);
// if the directory contains files from the depot, we can use
// the local path of one of those files to determine the local
// path for this directory
if ((String.IsNullOrEmpty(localPath)) && (files != null) && (files.Count > 0))
{
I downloaded the P4api.net API source code and observed within GetFileMetaData()
that the r.TaggedOutput == null
when the subject directory contains no file in it, just more sub directories. It could be my misunderstanding of the source code but I would think that the code should check for r.TaggedOutput == null
before running the FOR loop thereafter, please see code comment for exception location:
public IList<FileMetaData> GetFileMetaData(Options options, params FileSpec[] filespecs )
{
P4.P4Command fstatCmd = new P4.P4Command(_connection._p4server, "fstat", true, FileSpec.ToStrings(filespecs));
P4.P4CommandResult r = fstatCmd.Run(options);
if (r.Success != true)
{
P4Exception.Throw(r.ErrorList);
return null;
}
List<FileMetaData> value = new List<FileMetaData>();
foreach (P4.TaggedObject obj in r.TaggedOutput)
// Null Exception was caused by r.TaggedOutput=null when the sub dir has no file.
{
FileMetaData fmd = new FileMetaData();
fmd.FromFstatCmdTaggedData(obj);
value.Add(fmd);
}
return value;
}
How do I get around this problem as one can expect a depot directory to have either directories or files or both but GetFileMetaData()
seems to expect the dir always have files in it? Is there an option I have to specify for the passed-in "options" param that can prevent this exception? Or is there another API call to check for the existence of files within a directory that code can call before calling GetFileMetaData()
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
此错误已报告并已在 P4API.NET GA 版本中修复。我不确定何时发布,但您可以致电 Perforce 支持并询问。
同时,这里有一个可能的解决方法来查看目录是否为空。
基本上它使用与 GetFileMetaData 类似的逻辑,但使用较低级别的命令直接从服务器获取标记输出。然后,您可以在调用其他方法之前检查结果集是否存在目录中的任何文件。
This bug was reported and already fixed for the GA release of P4API.NET. I'm not sure when that is being released, but you can call Perforce Support and ask about it.
In the meantime, here's a possible work-around to see if a directory is empty or not.
Basically it's using similar logic as
GetFileMetaData
, but using a lower level command to get tagged output from the server directly. Then you can check the result set for the existence of any files in the directory before you call the other methods.