0

我运行从 P4 下载的 P4api.net 示例 C# 代码来遍历/depot我拥有的本地 P4 存储库。当示例代码尝试读取//depot/subdirAfor 子目录和文件时,对 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主题目录中没有文件时,只有更多的子目录。这可能是我对源代码的误解,但我认为代码应该在r.TaggedOutput == null之后运行 FOR 循环之前检查,请参阅代码注释以了解异常位置:

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()似乎期望目录中总是有文件?我必须为传入的“选项”参数指定一个可以防止此异常的选项吗?或者在调用 GetFileMetaData() 之前是否有另一个 API 调用来检查代码可以调用的目录中是否存在文件?预先感谢您的帮助。

4

1 回答 1

1

此错误已报告并已在 P4API.NET 的 GA 版本中修复。我不确定它何时发布,但您可以致电 Perforce 支持并询问相关信息。

同时,这里有一个可能的解决方法来查看目录是否为空。

String[] cmdargs = new String[1];
cmdargs[0] = depotPath + "/*";
P4Command cmd = new P4Command(rep, "files", true, cmdargs);
P4CommandResult results = cmd.Run(null);
if (results != null && results.TaggedOutput != null)
{
    foreach (TaggedObject obj in results.TaggedOutput)
    {
        // do something with file list if you want
    }
}
else
{                        
    Console.WriteLine("No files in this directory!");                        
}

基本上它使用与 类似的逻辑GetFileMetaData,但使用较低级别的命令直接从服务器获取标记输出。然后,您可以在调用其他方法之前检查结果集是否存在目录中的任何文件。

于 2012-01-19T16:23:47.497 回答