驱动器 Api 保存到文件夹,如果文件夹不存在,创建而不是保存
Drive Api save to folder, if folder doesnt exist, create than save
我正在使用 Google 驱动器 API 在那里保存(用作备份)数据库,它工作得很好,但如果我使用 ROOT
Api调用:
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
......build();
Drive.DriveApi.getRootFolder(mGoogleApiClient)
.createFile(mGoogleApiClient, metadataChangeSet, result.getDriveContents())
.setResultCallback(fileCallback);
保存文件的回调:
final public ResultCallback < DriveFolder.DriveFileResult > fileCallback = new
ResultCallback < DriveFolder.DriveFileResult > () {
@Override
public void onResult(DriveFolder.DriveFileResult result) {
if (!result.getStatus().isSuccess()) {
return;
}
Log.i(TAG, "Successfull !");
}
};
我知道我必须得到文件夹,但如果我这样做,我需要做一个回调来调用另一个回调然后保存?
没有办法直接在 FOLDER 中执行 .createNewFile 吗?不对文件夹执行另一个查询,检查文件夹是否存在而不是创建文件夹,而不是使用 DriveID,而不是创建文件?
请记住,在 GooDrive 宇宙中,树结构(文件夹、子文件夹...)是海市蜃楼。 Drive 是一个包含 objects(文件、文件夹)的平面系统,其中一个元数据字段是 'set of parent IDs',实际上构成了 parentobject 的概念 - childobject结构。实际上经典的树(一个 parent 很多 children)甚至没有被强制执行,所以 child object 可以 'appear' 更多 parent.
这个事实说明你不能一次创建 OS 类型的路径。必须先创建 objects (parents),然后才能将其 ID 插入 child objects 的元数据。
所以唯一的方法就是按照你说的去做:
if folder exists
return it's ID
else
return ID of newly created one
create a child object with parent's ID
... 这是我如何创建类型结构的示例:
/ MYROOT / 2015 / 2015-12
(其中 MYROOT、2015、2015-12 是 Drive root 的子文件夹)
new Thread(new Runnable() {
@Override
public void run() {
DriveId Id = getFolder( getFolder( getFolder(
Drive.DriveApi.getRootFolder(mGAC).getDriveId(), "MYROOT"),
"2015",
"2015-12"
);
}
}).start();
GoogleApiClient mGAC;
DriveId getFolder(DriveId parentId, String titl) {
DriveId dId = null;
if (parentId != null && titl != null) try {
ArrayList<Filter> fltrs = new ArrayList<>();
fltrs.add(Filters.in(SearchableField.PARENTS, parentId));
fltrs.add(Filters.eq(SearchableField.TITLE, titl));
fltrs.add(Filters.eq(SearchableField.MIME_TYPE, "application/vnd.google-apps.folder"));
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
MetadataBuffer mdb = null;
DriveApi.MetadataBufferResult rslt = Drive.DriveApi.query(mGAC, qry).await();
if (rslt.getStatus().isSuccess()) try {
mdb = rslt.getMetadataBuffer();
if (mdb.getCount() > 0)
dId = mdb.get(0).getDriveId();
} catch (Exception ignore) {}
finally { if (mdb != null) mdb.close(); }
if (dId == null) {
MetadataChangeSet meta = new Builder().setTitle(titl).setMimeType(UT.MIME_FLDR).build();
DriveFolderResult r1 = parentId.asDriveFolder().createFolder(mGAC, meta).await();
DriveFolder dFld = (r1 != null) && r1.getStatus().isSuccess() ? r1.getDriveFolder() : null;
if (dFld != null) {
MetadataResult r2 = dFld.getMetadata(mGAC).await();
if ((r2 != null) && r2.getStatus().isSuccess()) {
dId = r2.getMetadata().getDriveId();
}
}
}
} catch (Exception e) { e.printStackTrace(); }
return dId;
}
在“mdb.get(0).getDriveId()”区域,您可以看到当您尝试将经典树结构强加于驱动器。这里搜索可以return多个同名的object,所以我用第一个。这里应该有某种错误报告。
如您所见,可以用 'await()' 方法替换回调,只要将整个序列 [=47] =]线程(异步任务,线程,....)
不过,完成此操作的更优雅 (IMO) 选项是使用结果回调的递归调用。
fromPath(Drive.DriveApi.getRootFolder(mGAC).getDriveId(), "MYROOT/2015/2015-12/file.jpg");
....
void fromPath(final DriveId parentId, final String path) {
if (parentId != null && path != null) {
final int idx = path.indexOf('/');
if (idx < 0) {
// reached last path item - probably file name
// CREATE FILE WITH patentID AND QUIT
return; //--- DONE -------------------->>>
}
final String titl = path.substring(0, idx);
ArrayList<Filter> fltrs = new ArrayList<>();
fltrs.add(Filters.in(SearchableField.PARENTS, parentId));
fltrs.add(Filters.eq(SearchableField.TITLE, titl));
fltrs.add(Filters.eq(SearchableField.MIME_TYPE, UT.MIME_FLDR));
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
Drive.DriveApi.query(mGAC, qry).setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
@Override
public void onResult(DriveApi.MetadataBufferResult rslt) {
MetadataBuffer mdb = null;
if (rslt != null && rslt.getStatus().isSuccess()) {
try {
mdb = rslt.getMetadataBuffer();
for (Metadata md : mdb) {
if (md.isTrashed()) continue;
fromPath(md.getDriveId(), path.substring(idx + 1));
return; //+++ first found, NEXT +++++++>>>
}
} finally { if (mdb != null) mdb.close(); }
}
MetadataChangeSet meta = new Builder().setTitle(titl).setMimeType(UT.MIME_FLDR).build();
parentId.asDriveFolder().createFolder(mGAC, meta)
.setResultCallback(new ResultCallback<DriveFolderResult>() {
@Override
public void onResult(DriveFolderResult rslt) {
DriveFolder dFld = rslt != null && rslt.getStatus().isSuccess() ? rslt.getDriveFolder() : null;
if (dFld != null) {
dFld.getMetadata(mGAC).setResultCallback(new ResultCallback<MetadataResult>() {
@Override
public void onResult(MetadataResult rslt) {
if (rslt != null && rslt.getStatus().isSuccess()) {
fromPath(rslt.getMetadata().getDriveId(), path.substring(idx + 1));
return; //+++ created, NEXT +++++++>>>
}
}
});
}
}
});
}
});
}
}
注意事项:
当我反复调用这个序列时,使用最后一个 DriveId(如 2015-12)作为 JPEG 图像文件的 parent,我遇到了奇怪的行为,比如突然从 'Drive.DriveApi.getRootFolder(mGAC).getDriveId()'。它不应该发生,我认为这是 GDAA 中的错误。我将此归因于以下事实:在 GDAA 中使用的 DriveId 是 'invalid',直到文件夹被提交并且 ResourceId 在底层 REST Api 中被解析。不幸的是,没有 completion event 可用于创建文件夹,因此我通过在 onConnected() 中仅调用一次此序列并缓存 '2015-12's DriveId 以供以后用作图像的 parent 来解决此问题JPEG 文件。
实际上你可以看到它 here (createTree() 方法)尾部有文本文件,但是当我将 TEXT 切换为 JPEG 时,一切都崩溃了。
祝你好运
我正在使用 Google 驱动器 API 在那里保存(用作备份)数据库,它工作得很好,但如果我使用 ROOT
Api调用:
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
......build();
Drive.DriveApi.getRootFolder(mGoogleApiClient)
.createFile(mGoogleApiClient, metadataChangeSet, result.getDriveContents())
.setResultCallback(fileCallback);
保存文件的回调:
final public ResultCallback < DriveFolder.DriveFileResult > fileCallback = new
ResultCallback < DriveFolder.DriveFileResult > () {
@Override
public void onResult(DriveFolder.DriveFileResult result) {
if (!result.getStatus().isSuccess()) {
return;
}
Log.i(TAG, "Successfull !");
}
};
我知道我必须得到文件夹,但如果我这样做,我需要做一个回调来调用另一个回调然后保存?
没有办法直接在 FOLDER 中执行 .createNewFile 吗?不对文件夹执行另一个查询,检查文件夹是否存在而不是创建文件夹,而不是使用 DriveID,而不是创建文件?
请记住,在 GooDrive 宇宙中,树结构(文件夹、子文件夹...)是海市蜃楼。 Drive 是一个包含 objects(文件、文件夹)的平面系统,其中一个元数据字段是 'set of parent IDs',实际上构成了 parentobject 的概念 - childobject结构。实际上经典的树(一个 parent 很多 children)甚至没有被强制执行,所以 child object 可以 'appear' 更多 parent.
这个事实说明你不能一次创建 OS 类型的路径。必须先创建 objects (parents),然后才能将其 ID 插入 child objects 的元数据。
所以唯一的方法就是按照你说的去做:
if folder exists
return it's ID
else
return ID of newly created one
create a child object with parent's ID
... 这是我如何创建类型结构的示例:
/ MYROOT / 2015 / 2015-12
(其中 MYROOT、2015、2015-12 是 Drive root 的子文件夹)
new Thread(new Runnable() {
@Override
public void run() {
DriveId Id = getFolder( getFolder( getFolder(
Drive.DriveApi.getRootFolder(mGAC).getDriveId(), "MYROOT"),
"2015",
"2015-12"
);
}
}).start();
GoogleApiClient mGAC;
DriveId getFolder(DriveId parentId, String titl) {
DriveId dId = null;
if (parentId != null && titl != null) try {
ArrayList<Filter> fltrs = new ArrayList<>();
fltrs.add(Filters.in(SearchableField.PARENTS, parentId));
fltrs.add(Filters.eq(SearchableField.TITLE, titl));
fltrs.add(Filters.eq(SearchableField.MIME_TYPE, "application/vnd.google-apps.folder"));
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
MetadataBuffer mdb = null;
DriveApi.MetadataBufferResult rslt = Drive.DriveApi.query(mGAC, qry).await();
if (rslt.getStatus().isSuccess()) try {
mdb = rslt.getMetadataBuffer();
if (mdb.getCount() > 0)
dId = mdb.get(0).getDriveId();
} catch (Exception ignore) {}
finally { if (mdb != null) mdb.close(); }
if (dId == null) {
MetadataChangeSet meta = new Builder().setTitle(titl).setMimeType(UT.MIME_FLDR).build();
DriveFolderResult r1 = parentId.asDriveFolder().createFolder(mGAC, meta).await();
DriveFolder dFld = (r1 != null) && r1.getStatus().isSuccess() ? r1.getDriveFolder() : null;
if (dFld != null) {
MetadataResult r2 = dFld.getMetadata(mGAC).await();
if ((r2 != null) && r2.getStatus().isSuccess()) {
dId = r2.getMetadata().getDriveId();
}
}
}
} catch (Exception e) { e.printStackTrace(); }
return dId;
}
在“mdb.get(0).getDriveId()”区域,您可以看到当您尝试将经典树结构强加于驱动器。这里搜索可以return多个同名的object,所以我用第一个。这里应该有某种错误报告。
如您所见,可以用 'await()' 方法替换回调,只要将整个序列 [=47] =]线程(异步任务,线程,....)
不过,完成此操作的更优雅 (IMO) 选项是使用结果回调的递归调用。
fromPath(Drive.DriveApi.getRootFolder(mGAC).getDriveId(), "MYROOT/2015/2015-12/file.jpg");
....
void fromPath(final DriveId parentId, final String path) {
if (parentId != null && path != null) {
final int idx = path.indexOf('/');
if (idx < 0) {
// reached last path item - probably file name
// CREATE FILE WITH patentID AND QUIT
return; //--- DONE -------------------->>>
}
final String titl = path.substring(0, idx);
ArrayList<Filter> fltrs = new ArrayList<>();
fltrs.add(Filters.in(SearchableField.PARENTS, parentId));
fltrs.add(Filters.eq(SearchableField.TITLE, titl));
fltrs.add(Filters.eq(SearchableField.MIME_TYPE, UT.MIME_FLDR));
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
Drive.DriveApi.query(mGAC, qry).setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
@Override
public void onResult(DriveApi.MetadataBufferResult rslt) {
MetadataBuffer mdb = null;
if (rslt != null && rslt.getStatus().isSuccess()) {
try {
mdb = rslt.getMetadataBuffer();
for (Metadata md : mdb) {
if (md.isTrashed()) continue;
fromPath(md.getDriveId(), path.substring(idx + 1));
return; //+++ first found, NEXT +++++++>>>
}
} finally { if (mdb != null) mdb.close(); }
}
MetadataChangeSet meta = new Builder().setTitle(titl).setMimeType(UT.MIME_FLDR).build();
parentId.asDriveFolder().createFolder(mGAC, meta)
.setResultCallback(new ResultCallback<DriveFolderResult>() {
@Override
public void onResult(DriveFolderResult rslt) {
DriveFolder dFld = rslt != null && rslt.getStatus().isSuccess() ? rslt.getDriveFolder() : null;
if (dFld != null) {
dFld.getMetadata(mGAC).setResultCallback(new ResultCallback<MetadataResult>() {
@Override
public void onResult(MetadataResult rslt) {
if (rslt != null && rslt.getStatus().isSuccess()) {
fromPath(rslt.getMetadata().getDriveId(), path.substring(idx + 1));
return; //+++ created, NEXT +++++++>>>
}
}
});
}
}
});
}
});
}
}
注意事项:
当我反复调用这个序列时,使用最后一个 DriveId(如 2015-12)作为 JPEG 图像文件的 parent,我遇到了奇怪的行为,比如突然从 'Drive.DriveApi.getRootFolder(mGAC).getDriveId()'。它不应该发生,我认为这是 GDAA 中的错误。我将此归因于以下事实:在 GDAA 中使用的 DriveId 是 'invalid',直到文件夹被提交并且 ResourceId 在底层 REST Api 中被解析。不幸的是,没有 completion event 可用于创建文件夹,因此我通过在 onConnected() 中仅调用一次此序列并缓存 '2015-12's DriveId 以供以后用作图像的 parent 来解决此问题JPEG 文件。
实际上你可以看到它 here (createTree() 方法)尾部有文本文件,但是当我将 TEXT 切换为 JPEG 时,一切都崩溃了。
祝你好运