什么是最简单的方法从android.net.Uri对象持有一个文件:类型转换为java.io.File对象在Android?

我尝试了下面的方法,但不管用:

File file = new File(Environment.getExternalStorageDirectory(), "read.me");
Uri uri = Uri.fromFile(file);
File auxFile = new File(uri.toString());
assertEquals(file.getAbsolutePath(), auxFile.getAbsolutePath());

当前回答

通过下面的代码,我能够获得adobe应用程序共享pdf文件作为流,并保存到android应用程序路径

Android.Net.Uri fileuri =
    (Android.Net.Uri)Intent.GetParcelableExtra(Intent.ExtraStream);

    fileuri i am getting as {content://com.adobe.reader.fileprovider/root_external/
                                        data/data/com.adobe.reader/files/Downloads/sample.pdf}

    string filePath = fileuri.Path;

   filePath I am gettings as root_external/data/data/com.adobe.reader/files/Download/sample.pdf

      using (var stream = ContentResolver.OpenInputStream(fileuri))
      {
       byte[] fileByteArray = ToByteArray(stream); //only once you can read bytes from stream second time onwards it has zero bytes

       string fileDestinationPath ="<path of your destination> "
       convertByteArrayToPDF(fileByteArray, fileDestinationPath);//here pdf copied to your destination path
       }
     public static byte[] ToByteArray(Stream stream)
        {
            var bytes = new List<byte>();

            int b;
            while ((b = stream.ReadByte()) != -1)
                bytes.Add((byte)b);

            return bytes.ToArray();
        }

      public static string convertByteArrayToPDF(byte[] pdfByteArray, string filePath)
        {

            try
            {
                Java.IO.File data = new Java.IO.File(filePath);
                Java.IO.OutputStream outPut = new Java.IO.FileOutputStream(data);
                outPut.Write(pdfByteArray);
                return data.AbsolutePath;

            }
            catch (System.Exception ex)
            {
                return string.Empty;
            }
        }

其他回答

你想要的是…

new File(uri.getPath());

... ,而不是……

new File(uri.toString());

笔记

对于android.net.Uri对象,它被命名为uri并完全按照问题中创建,uri. tostring()返回一个“file:///mnt/sdcard/myPicture.jpg”格式的字符串,而uri. getpath()返回一个“/mnt/sdcard/myPicture.jpg”格式的字符串。 我知道在Android系统中文件存储有一些细微差别。在这个回答中,我的意图是准确地回答提问者所问的问题,而不是深究其中的细微差别。

在寻找了很长一段时间后,这对我来说是有效的:

File file = new File(getPath(uri));


public String getPath(Uri uri) 
    {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
        if (cursor == null) return null;
        int column_index =             cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String s=cursor.getString(column_index);
        cursor.close();
        return s;
    }

一些库需要文件对象的过程,如改造,一些图像编辑器等。 将URI转换为文件对象或任何类似的东西,我们有一种方法,这是支持所有android旧版本和即将到来的版本。

步骤1:

你必须在FilesDir中创建一个新文件,这个文件对于其他与我们的文件和扩展名相同的应用程序是不可读的。

步骤2:

您必须通过使用InputStream复制URI的内容来创建一个文件。

File f = getFile(getApplicationContext(), uri);

public static File getFile(Context context, Uri uri) throws IOException {
    File destinationFilename = new File(context.getFilesDir().getPath() + File.separatorChar + queryName(context, uri));
    try (InputStream ins = context.getContentResolver().openInputStream(uri)) {
        createFileFromStream(ins, destinationFilename);
    } catch (Exception ex) {
        Log.e("Save File", ex.getMessage());
        ex.printStackTrace();
    }
    return destinationFilename;
}

public static void createFileFromStream(InputStream ins, File destination) {
    try (OutputStream os = new FileOutputStream(destination)) {
        byte[] buffer = new byte[4096];
        int length;
        while ((length = ins.read(buffer)) > 0) {
            os.write(buffer, 0, length);
        }
        os.flush();
    } catch (Exception ex) {
        Log.e("Save File", ex.getMessage());
        ex.printStackTrace();
    }
}

private static String queryName(Context context, Uri uri) {
    Cursor returnCursor =
            context.getContentResolver().query(uri, null, null, null, null);
    assert returnCursor != null;
    int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
    returnCursor.moveToFirst();
    String name = returnCursor.getString(nameIndex);
    returnCursor.close();
    return name;
}

public String getRealPathFromURI(Uri uri) {

    String result;
    Cursor cursor = getContentResolver().query(uri, null, null, null, null);
    if (cursor == null) {
        result = uri.getPath();
        cursor.close();
        return result;
    }
    cursor.moveToFirst();
    int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
    result = cursor.getString(idx);
    cursor.close();
    return result;
}

然后使用从URI中获取文件:

        File finalFile = newFile(getRealPathFromURI(uri));

——希望能帮到你----

要正确地使用context uri获取文件, 感谢来自@Mohsents, @Bogdan Kornev, @CommonsWare, @Juan Camilo Rodriguez的回答Durán;

我从uri中创建了一个inputStream,并使用这个iStream创建了一个临时文件,最后我能够从这个文件中提取uri和路径。

fun createFileFromContentUri(fileUri : Uri) : File{

    var fileName : String = ""

    fileUri.let { returnUri ->
        requireActivity().contentResolver.query(returnUri,null,null,null)
    }?.use { cursor ->
        val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
        cursor.moveToFirst()
        fileName = cursor.getString(nameIndex)
    }
    
    //  For extract file mimeType
    val fileType: String? = fileUri.let { returnUri ->
        requireActivity().contentResolver.getType(returnUri)
    }

    val iStream : InputStream = requireActivity().contentResolver.openInputStream(fileUri)!!
    val outputDir : File = context?.cacheDir!!
    val outputFile : File = File(outputDir,fileName)
    copyStreamToFile(iStream, outputFile)
    iStream.close()
    return  outputFile
}

fun copyStreamToFile(inputStream: InputStream, outputFile: File) {
    inputStream.use { input ->
        val outputStream = FileOutputStream(outputFile)
        outputStream.use { output ->
            val buffer = ByteArray(4 * 1024) // buffer size
            while (true) {
                val byteCount = input.read(buffer)
                if (byteCount < 0) break
                output.write(buffer, 0, byteCount)
            }
            output.flush()
        }
    }
}