java - 如何修复 Android-Studio 中 Uri-Path 的 "FileNotFoundException"(没有此类文件或目录)错误?

标签 java android android-intent

我正在编写一个应用程序来将文件(图片)保存为 csv 文件中的列指定的特定名称。用户必须首先使用文件浏览器选择 csv,然后该文件将被复制到我的 Dir-Data 目录。

一切正常,但似乎我从File src Object获得的路径不适用于该操作。 我预计这里会出现明显的错误(第二个代码框) 如果这是明显/容易避免的,请提前告知,这是我的第一个 Android 项目。

我已经尝试使用具有不同参数类型的不同复制函数,并且还尝试了其他格式,例如 uri.toString() 给出的字符串。

//CSV 开场白

    public void performFileSearch() {

        // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file
        // browser.
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);

        // Filter to only show results that can be "opened"
        intent.addCategory(Intent.CATEGORY_OPENABLE);

        // Filter to show only  .csv  using the image MIME data type.
        // For all it would be "*/*".
        intent.setType("text/comma-separated-values");

        startActivityForResult(intent, READ_REQUEST_CODE);

    }

//创建路径

@Override

public void onActivityResult(int requestCode, int resultCode,
                                 Intent resultData) {

        if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK)
        {

            if (resultData != null) {
                Uri path = resultData.getData();
                stringUri = path.getPath();
                File src = new File(stringUri);
                File destination = new File(getFilesDir().getPath());

                try {
                    copyDirectoryOneLocationToAnotherLocation(src,destination);
                }
                catch(IOException e) {
                    e.printStackTrace();
                    System.out.print("error in upload");
                }

                Toast.makeText(MainActivity.this, "Path: "+stringUri , Toast.LENGTH_SHORT).show();

            }


        }
    }

//来自 StackOverflow 的复制操作

    public static void copyDirectoryOneLocationToAnotherLocation(File sourceLocation, File targetLocation)
            throws IOException {

        if (sourceLocation.isDirectory()) {
            if (!targetLocation.exists()) {
                targetLocation.mkdir();
            }

            String[] children = sourceLocation.list();
            for (int i = 0; i < sourceLocation.listFiles().length; i++) {

                copyDirectoryOneLocationToAnotherLocation(new File(sourceLocation, children[i]),
                        new File(targetLocation, children[i]));
            }
        } else {

            InputStream in = new FileInputStream(sourceLocation);

            OutputStream out = new FileOutputStream(targetLocation);

            // Copy the bits from instream to outstream
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();
        }

    }

我希望将所选文件复制到我的 data/data/... 目录中,以便稍后在应用程序中使用。

但是:我从对象获得的路径对我不起作用

最佳答案

谢谢@Mike M.,使用 getContentResolver() 的技巧在尝试后给了我答案。

最后使用了其他复制函数并重新设计了 onActivityResult();

public void onActivityResult(int requestCode, int resultCode,
                             Intent resultData) {

    if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK)
    {

        if (resultData != null) {
            try {
                String destination = getFilesDir().getPath();
                InputStream src = getContentResolver().openInputStream(resultData.getData()); // use the uri to create an inputStream
                try {

                    convertInputStreamToFile(src, destination);
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.print("error in upload");
                }
            } catch (FileNotFoundException ex) {
                }
            String destination = getFilesDir().getPath();
            Toast.makeText(MainActivity.this, "Success!: CSV-File copyed to : " +destination  , Toast.LENGTH_SHORT).show();
        }
    }


}
public static void convertInputStreamToFile(InputStream is, String destination) throws IOException
{
    OutputStream outputStream = null;
    try
    {
        File file = new File(destination + "/Student.csv");
        outputStream = new FileOutputStream(file);

        int read = 0;
        byte[] bytes = new byte[1024];
        while ((read = is.read(bytes)) != -1) {
            outputStream.write(bytes, 0, read);
        }
    }
    finally
    {
        if(outputStream != null)
        {
            outputStream.close();
        }
    }
}

关于java - 如何修复 Android-Studio 中 Uri-Path 的 "FileNotFoundException"(没有此类文件或目录)错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56011090/

相关文章:

android - 自定义首选项标题字体大小大于 android 5 中的标准首选项

android - 在 Android 中打开布局而不触摸通知

java - 如何使用 JPA (Java EE) 将 XML 数据结构映射到数据库

java - Intersystems Caché 与 Java Gateway - 将参数作为 java.io.FileInputStream 传递

java - Android Studio 将数据保存到数据库中

android ACTION_VIDEO_CAPTURE 不保存视频

android - Android 中的 Intent 解析

java - GNU Octave - base64_decode/base64_encode

android - 未出现在 xml 中定义的 SplashScreen 方法(无 Activity )

java - 如何将Android中的LocationResult类转换为Location类?