API GetFileMetaData() Perforce P4.NET возвращает исключение NullReferenceException

Я запустил образец кода C# на P4api.net, загруженный с P4, чтобы пройти по локальному 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))
        {

Я скачал исходный код API P4api.net и наблюдал в 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() Кажется, в каталоге всегда есть файлы? Есть ли опция, которую я должен указать для переданного параметра "options", который может предотвратить это исключение? Или существует другой вызов API для проверки существования файлов в каталоге, который код может вызвать перед вызовом GetFileMetaData()? Спасибо заранее за вашу помощь.

1 ответ

Эта ошибка была зарегистрирована и уже исправлена ​​в выпуске GA P4API.NET. Я не уверен, когда это будет выпущено, но вы можете позвонить в службу поддержки 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, но используя команду более низкого уровня, чтобы получить помеченный вывод с сервера напрямую. Затем вы можете проверить набор результатов на наличие любых файлов в каталоге, прежде чем вызывать другие методы.

Другие вопросы по тегам