上传到Google云端硬盘文件未找到例外

时间:2012-11-29 20:46:43

标签: java android file

我想以编程方式访问特定的Excel电子表格,该电子表格将包含在我的项目文件夹中并上传到Google云端硬盘。我将电子表格包含在我的src文件夹中并使用以下代码:

private void saveFileToDrive() {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {

                    URL fileURL = getClass().getClassLoader().getResource("Untitled spreadsheet.xlsx");
                    String filePath2 = fileURL.getPath();

                    java.io.File fileContent = new java.io.File(filePath2);
                    FileContent mediaContent = new FileContent("application/vnd.ms-excel", fileContent);

                    File body = new File();
                    body.setTitle(fileContent.getName());
                    body.setMimeType("application/vnd.ms-excel");


                    File file = service.files().insert(body, mediaContent).setConvert(true).execute();

                    if (file != null) {
                        showToast("File uploaded: " + file.getTitle());
                    }
                    else
                             ;
                } catch (UserRecoverableAuthIOException e) {

                    startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
                } catch (IOException e) {

                    e.printStackTrace();
                }
            }
        });
        t.start();
    }

但是,我一直收到以下FileNotFoundException:

11-29 14:43:45.189: W/System.err(21133): java.io.FileNotFoundException: /file:/data/app/com.example.drivequickstart-2.apk!/Untitled spreadsheet.xlsx: open failed: ENOENT (No such file or directory)

有谁知道造成这种情况的原因是什么?

编辑: 我尝试按照以下建议修改我的代码:

private void saveFileToDrive() {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {

                      String mime = "application/vnd.ms-excel";
                     InputStream in = getApplicationContext().getAssets().open("Untitled spreadsheet.xlsx");
                     InputStreamContent content = new InputStreamContent(mime, in);;

                        File body = new File();
                        body.setTitle("Untitled spreadsheet");
                        body.setMimeType("application/vnd.ms-excel");


                        File file = service.files().insert(body, content).setConvert(true).execute();

                        if (file != null) {
                            showToast("File uploaded: " + file.getTitle());
                        }
                        else
                                 ;
                    } catch (UserRecoverableAuthIOException e) {

                        startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
                    } catch (IOException e) {

                        e.printStackTrace();
                    }
                }
            });
            t.start();
        }

然而,这给了我以下错误:

11-29 20:31:08.118: E/AndroidRuntime(9833): java.lang.IllegalArgumentException
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.google.common.base.Preconditions.checkArgument(Preconditions.java:76)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.google.api.client.googleapis.media.MediaHttpUploader.getMediaContentLength(MediaHttpUploader.java:328)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.google.api.client.googleapis.media.MediaHttpUploader.executeUploadInitiation(MediaHttpUploader.java:347)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.google.api.client.googleapis.media.MediaHttpUploader.upload(MediaHttpUploader.java:266)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:408)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:328)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:449)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at com.example.drivequickstart.MainActivity$3.run(MainActivity.java:303)
11-29 20:31:08.118: E/AndroidRuntime(9833):     at java.lang.Thread.run(Thread.java:864)

并指向该行:File file = service.files().insert(body, content).setConvert(true).execute();仔细观察后,我发现InputStreamContent的长度为-1,因此问题可能源自那里。

2 个答案:

答案 0 :(得分:1)

您使用Java惯用语ClassLoader.getResource()加载CLASSPATH中的资源。但是,这不是我们在Android上的方式。

您将文件放在assets/目录或res/raw/中,然后使用AssetManagerR.raw.untitled_spreadsheet.xlsx等标识符进行检索。

请参阅the official guide

  

虽然不常见,但您可能需要访问原始文件   目录。如果您这样做,那么在res /中保存文件将不起作用   你,因为从res读取资源的唯一方法是使用   资源ID。相反,您可以将资源保存在资产中/   。目录

     

保存在assets /目录中的文件没有给出资源ID,所以   您无法通过R类或XML资源引用它们。   相反,您可以像正常一样查询assets /目录中的文件   文件系统并使用AssetManager读取原始数据。

     

但是,如果您只需要能够读取原始数据(例如   视频或音频文件),然后将文件保存在res / raw /目录中   使用openRawResource()读取字节流。

如果您将文件放在assets/sheet.xlsx

中,请在代码中说明
String mime = "application/vnd.ms-excel";
InputStream in = ctx.getAssets().open("sheet.xlsx");
InputStreamContent content = new InputStreamContent(mime, in);

其中ctxContext。由于ActivityContext,如果您碰巧在ctx内编写此代码,则可以跳过getAssets()并直接调用Activity

请注意,我没有使用FileContent:而是选择InputStreamContent,因为您实际上没有java.io.File个对象,只有an input stream

基本上,您要求云端硬盘客户端:“从此本地流中读取字节,上传它们并以名称$ NAME”进行访问。名称$NAME通过com.google.api.services.drive.model.File对象的title字段提供给服务,该字段可以是您喜欢的任何内容 - 我认为它也可以包含目录分隔符。

这是指向Javadoc for Google Drive V2

的链接

答案 1 :(得分:0)

要解决“导致此问题的原因?”的问题,请参阅讨论here(评论#13)。

  

这是一个简单的原因,你没有给它一个有效的文件路径。您   从类加载器获取资源,该资源是   来自一个罐子(实际上从来没有打包过   文件系统)。

     

因此,当您询问路径的资源的URL时   url.getPath()你回来了   (在你的情况下)文件:/data/app/com.example.drivequickstart-2.apk!/ Untitled spreadsheet.xlsx

     

这不是合法的'file:'url string!

他还提出了一个非常恰当的方法来解决这个问题:

  

你应该做的只是向构造函数提供String   由URL.toString()返回。你应该得到什么是某种形式   注册的url类型仍然指向jar文件,但是   VM中的url解析程序知道如何处理。