从URI或原始文件路径重新创建文件时文件长度为0 [getExternalFilesDir(String type)vs getFilesDir()]

时间:2016-02-10 04:30:32

标签: java android azure-blob-storage

首先有一点背景知识:此应用程序拍摄照片并上传到Azure blob存储。

图片使用getApplicationContext().getFilesDir();

存储在文件(内部存储空间)中

要上传,我需要调用uploadFromFile(..)函数,如下所示: CloudBlockBlob.uploadFromFile(String path);

Azure SDK的uploadFromFile函数如下所示:

public void uploadFromFile(final String path) throws StorageException, IOException {
        uploadFromFile(path, null /* accessCondition */, null /* options */, null /* opContext */);
    }

public void uploadFromFile(final String path, final AccessCondition accessCondition, BlobRequestOptions options,
            OperationContext opContext) throws StorageException, IOException {
        File file = new File(path);
        long fileLength = file.length();
        InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
        this.upload(inputStream, fileLength, accessCondition, options, opContext);
        inputStream.close();
    }

问题出在long fileLength = file.length();行,其中fileLength为0.

我已针对存储目录使用Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);进行了测试。这有效。

我需要使用内部存储与外部存储,因为这是该项目特别需要的。

编辑:Android File文档未提及此行为。我假设这可能与使用应用内部存储有关。

编辑:添加一些代码

我正在向我的相机意图发送File mPhotoFile。这将包含照片。 mPhotoFileUri包含此文件的URI。以下是使用文件路径的代码。

File file = new File(mPhotoFile.getPath()); // value -> /data/user/0/com.example.devpactapp/files/JPEG_20160209_234929_1936823724.jpg
boolean fileExists = file.exists();         // true
long fileLength = file.length();            // length 0

以下是从URI获取文件的代码。

File file = new File(mPhotoFileUri.getPath());  // value -> /data/user/0/com.example.devpactapp/files/JPEG_20160209_235534_-1059496729.jpg
boolean fileExists = file.exists();             // true
long fileLength = file.length();                // length 0

我必须将此文件的路径传递给uploadFromFile函数。

我的回答'

中提到的解决方法

3 个答案:

答案 0 :(得分:1)

即使我没有掌握所有信息,我也会拨打电话,说明您所提供的路径中缺少该文件。 javadoc for length()具体提到此案例将返回0。

因此,在对文件执行任何操作之前,请尝试检查exists()。

答案 1 :(得分:0)

使用内部存储时,文件路径不同。我认为它存储在/ storage /模拟最新设备中。检查文件路径。并查看您是否使用绝对路径创建文件。

答案 2 :(得分:0)

找到了解决方法。这是我用来获取传递给Camera intent的文件的函数。

    // Create a File object for storing the photo
    private File createImageFile() throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = getApplicationContext().getFilesDir();

    mPhotoFileExists = true;

    // check if access to external storage exists
    // if returned true, return the new file
    // if returned false, user could have been requested for access
    // so, need to check if permission is available now
    // if still not available, return null

    if(haveWritePermissions())
        return File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );
    return null;
    }

我将storageDir从getApplicationContext().getFilesDir();更改为getApplicationContext.getExternalFilesDir(null);

文档:getExternalFilesDir(String type)getFilesDir()

我通过了null,因为我不想放Environment.DIRECTORY_PICTURES,这会让Media Scanner找到图像文件。

据我所知,这绝不是一个“修复”。仍在寻找关于为什么getFilesDir()导致此问题的答案。

编辑:非常紧迫的原因,为什么这不是一个好的解决方案 - 外部存储可能并不总是可用,并且在这种情况下不会有任何解决方法。此外,任何其他具有权限WRITE_EXTERNAL_STORAGE的应用都可以在此处撰写。因此,也没有强制执行安全措施。