我试图列出在谷歌驱动器文件夹中找到的所有文件,查询似乎工作,但当我试图使用.getFiles()
获得文件列表的列表是空的。
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final String CREDENTIALS_FILE_PATH = "/serv_acc.json";
private static final String SERVICE_ACCOUNT = "xxxxxxxxx.iam.gserviceaccount.com";
private static final String APPLICATION_NAME = "ZZZ-bco-eXXX_oo";
private static final List<String> SCOPES = Arrays.asList(DriveScopes.DRIVE);
private static final String ROOT_FOLDER = "XXXXXXXXXXXXXX";
private static final String projection = "nextPageToken, files(id, name)";
private static Drive driveService;
public static void buildApiService() throws IOException, GeneralSecurityException {
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
InputStream resourceAsStream = GoogleDriveApplication.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(
ServiceAccountCredentials.fromStream(resourceAsStream).createScoped(SCOPES).createDelegated(SERVICE_ACCOUNT));
driveService = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer).setApplicationName(APPLICATION_NAME).build();
}
public static List<File> getChildren(String id) throws IOException {
String query = "'" + id + "'" + " in parents";
FileList directChildren = driveService.files().list()
.setQ(query).setFields(projection).execute();
System.out.println(directChildren.isEmpty()); // False
System.out.println(directChildren.size()); // 3
System.out.println(directChildren.getFiles().isEmpty()); // True
...
}
public static void main(String[] args) throws GeneralSecurityException, IOException {
buildApiService();
....
}
该文件夹如下所示:
1个子文件夹,1个zip(1,63 Go),1个Xlsx(200Kb)!
请注意:
。当其他进程使用相同的凭据时,相同的凭据在相同的文件夹中起作用(Python代码)
。相同的Java代码可用于其他文件夹
编辑2:我用Python编写了同样的代码。没有对证书或Google驱动器文件夹(权限,权限等)进行任何更改,它工作正常。
# The needed import for service account credentials:
from oauth2client.service_account import ServiceAccountCredentials
from googleapiclient.http import MediaIoBaseDownload
from apiclient.discovery import build
from getfilelistpy import getfilelist
import io
import flatdict
import os
scope = ['https://www.googleapis.com/auth/drive']
# Parsing JSON credentials for a service account:
credentials = ServiceAccountCredentials.from_json_keyfile_name('C:/serv_acc.json', scope)
service = build('drive', 'v3', credentials=credentials)
topFolderId = 'XXXXXXXXXXXXXX'
resource = {
"service_account": credentials,
"id": topFolderId,
"fields": "files(id,name)",
}
res = getfilelist.GetFileList(resource)
print(dict(res))
服务帐户是有权访问对外部用户打开的文件夹的用户组的一部分。
2条答案
按热度按时间ubbxdtey1#
如果您收到的
200
响应为空列表,并且您知道该文件夹包含一些文件,则最可能的原因是该文件夹未与服务帐户共享。From what I see in your code, when setting up the credentials you used
createDelegated(SERVICE_ACCOUNT)
, whereSERVICE_ACCOUNT
is just thexxxxxxxxx.iam.gserviceaccount.com
address of the service account that you're using. The documentation states that if the service account has domain-wide delegation you have to specify the user that you want to impersonate (so if the folder is owned by user@yourdomain.com, you have to use that address instead):如果凭据支持域范围的委托,则创建标识的副本,以便它模拟指定的用户;否则,返回相同的示例。
因此,如果你已经为你的服务帐户设置了域范围的委派,你需要首先模拟文件夹的所有者,或者其他有权访问该文件夹的人。否则,你需要首先使用你的服务帐户share该文件夹。
参考文献:
d5vmydt92#
服务帐户是一个虚拟用户,它有自己的Google Drive帐户。它不返回文件的原因是你还没有上传任何文件。
如果你的个人google drive账户上有一个目录,你可以使用服务账户的电子邮件地址,并与服务账户共享该目录,这样服务账户就可以访问该目录中的任何文件。
如果你有一个google workspace帐户,你也可以配置域范围的授权,允许服务帐户访问workspace域中的任何内容。