调用Google Drive API创建文件时抛出FileNotFoundException的原因咨询
问题:调用createFile方法抛出FileNotFoundException的原因是什么?
我有一个集成Firebase的谷歌应用,支持用户登录并存储应用数据。GoogleSignInOptions配置如下:
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN) .requestEmail() .requestScopes(Scope(Scopes.DRIVE_APPFOLDER)) .build()
createFile方法定义如下:
public Task<String> createFile() { return Tasks.call(mExecutor, () -> { File fileMetadata = new File(); fileMetadata.setName("profile.json"); fileMetadata.setParents(Collections.singletonList("appDataFolder")); java.io.File filePath = new java.io.File("profile.json"); FileContent mediaContent = new FileContent("application/json", filePath); File file = mDriveService.files().create(fileMetadata, mediaContent) .setFields("id") .execute(); return file.getId(); }); }
但调用该方法时抛出异常:java.io.FileNotFoundException: profile.json (No such file or directory),请问产生该异常的原因是什么?补充说明:当前在应用的调试版本中进行测试。
回答
这个异常的核心原因很明确:你代码里的java.io.File("profile.json")只是声明了一个文件路径,但这个路径对应的实际文件在设备上根本不存在,当FileContent尝试读取这个文件的内容来上传到Drive时,自然就会抛出找不到文件的异常。
具体拆解下可能的触发场景:
- 本地未创建目标文件:你没有提前在指定路径下创建
profile.json文件,也没有写入任何内容。java.io.File对象只是路径的抽象,不会自动创建实际文件。 - 路径指向错误:在Android应用中,直接使用相对路径
"profile.json"会指向当前工作目录,但这个目录通常不是你预期的应用私有存储路径,甚至可能没有读写权限,导致文件无法被找到或创建。
针对这个问题,你可以这样修复:
方案1:在应用私有存储中创建文件并写入内容
Android应用推荐使用内部存储来存放私有文件,避免路径混乱和权限问题:
public Task<String> createFile(Context context) { // 需要传入Context获取存储路径 return Tasks.call(mExecutor, () -> { // 1. 在应用内部存储创建profile.json文件 java.io.File internalFile = new java.io.File(context.getFilesDir(), "profile.json"); // 2. 写入示例JSON内容(替换成你实际的应用数据) try (FileWriter writer = new FileWriter(internalFile)) { writer.write("{\"username\":\"testUser\",\"email\":\"test@example.com\"}"); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("Failed to write profile data", e); } // 3. 后续正常执行Drive上传逻辑 File fileMetadata = new File(); fileMetadata.setName("profile.json"); fileMetadata.setParents(Collections.singletonList("appDataFolder")); FileContent mediaContent = new FileContent("application/json", internalFile); File file = mDriveService.files().create(fileMetadata, mediaContent) .setFields("id") .execute(); return file.getId(); }); }
方案2:创建空文件上传(如果不需要预填充内容)
如果你只是需要上传一个空的JSON文件,可以先创建空文件再上传:
public Task<String> createFile() { return Tasks.call(mExecutor, () -> { java.io.File filePath = new java.io.File("profile.json"); // 先检查文件是否存在,不存在则创建 if (!filePath.exists()) { // 注意:在Android中直接创建可能有权限问题,建议还是用内部存储路径 boolean created = filePath.createNewFile(); if (!created) { throw new RuntimeException("Failed to create empty profile.json file"); } } // 后续上传逻辑不变 File fileMetadata = new File(); fileMetadata.setName("profile.json"); fileMetadata.setParents(Collections.singletonList("appDataFolder")); FileContent mediaContent = new FileContent("application/json", filePath); File file = mDriveService.files().create(fileMetadata, mediaContent) .setFields("id") .execute(); return file.getId(); }); }
另外提醒下,调试版本中也要注意权限配置:如果是访问外部存储,需要在Manifest中声明READ_EXTERNAL_STORAGE/WRITE_EXTERNAL_STORAGE权限,不过优先推荐用内部存储,不需要额外权限。
内容的提问来源于stack exchange,提问作者G.Bee
相关产品推荐
相关产品推荐

