Get folder hierarchy with Google Drive API [C# / .

2020-01-29 19:10发布

I am looking for an elegant way to get the folder hierarchy, beginning with my root folder, using the C# Google Drive API V3.

Currently, you can get the root folder and its parents by

var getRequest = driveService.Files.Get("root");
getRequest.Fields = "parents";
var file = getRequest.Execute();

but I am looking for a way to get the children, not the parents, so I can recursively go down the file structure. Setting getRequest.Fields = 'children' is not a valid field option.

2条回答
叼着烟拽天下
2楼-- · 2020-01-29 19:51

recursively fetching children is a very time consuming way to fetch the full hierarchy. Much better is to run a query to fetch all folders in a single GET (well it might take more than one if you have more than 1,000 folders) and then traverse their parent properties to build up the hierarchy in memory. Bear in mind that (afaik) there is nothing that prevents a folder hierarchy being cyclic, thus folder1 owns folder2 owns folder3 owns folder1, so whichever strategy you follow, check that you aren't in a loop.

If you're new to GDrive, it's important to realise early on that Folders are simply labels, rather than containers. So cyclic relationships and files with multiple parents is quite normal. They were originally called Collections, but got renamed to Folders to appease those members of the community that couldn't get their head around labels.

查看更多
老娘就宠你
3楼-- · 2020-01-29 19:53

I hope this is the answer you were looking for. getHeirarchy Recursively digs Google Drive and stores the file titles into a text file.

public System.IO.StreamWriter w = new System.IO.StreamWriter("Hierarchy.txt", false);
string intend = "     ";

private void getHierarchy(Google.Apis.Drive.v2.Data.File Res, DriveService driveService)
{
    if (Res.MimeType == "application/vnd.google-apps.folder")
    {
        w.Write(intend + Res.Title + " :" + Environment.NewLine);
        intend += "     ";

        foreach (var res in ResFromFolder(driveService, Res.Id).ToList())
            getHierarchy(res, driveService);

        intend = intend.Remove(intend.Length - 5);
    }
    else
    {
        w.Write(intend + Res.Title + Environment.NewLine);
    }
}

You can call the function something like:

w.Write("My Drive:" + Environment.NewLine);

foreach (var Res in ResFromFolder(driveService, "root").ToList())
    getHierarchy(Res, driveService);

w.Close();

Here, root can be replaced with the ID of any Directory to get it's structure. This will generate the entire Drive's structure.

The ResFromFolder method returns a list of Google.Apis.Drive.v2.Data.File metadata contained in a directory.

public List<Google.Apis.Drive.v2.Data.File> ResFromFolder(DriveService service, string folderId)
{
    var request = service.Children.List(folderId);
    request.MaxResults = 1000;

    List<Google.Apis.Drive.v2.Data.File> TList = new List<Google.Apis.Drive.v2.Data.File>();
    do
    {
        var children = request.Execute();
        foreach (ChildReference child in children.Items)
        {
            TList.Add(service.Files.Get(child.Id).Execute());
        }
        request.PageToken = children.NextPageToken;
    } while (!String.IsNullOrEmpty(request.PageToken));

    return TList;
}

This code produces output something like

enter image description here

However as pinoyyid mentioned, it does consume a good deal of time if Drive contains a large number of files and folders.

查看更多
登录 后发表回答