微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何修复 kotlin 中 FileInputStream 和 FileDescriptor 的错误路径

如何解决如何修复 kotlin 中 FileInputStream 和 FileDescriptor 的错误路径

FILE 是使用 cacheDir 中的 URI 创建的,但是当我尝试获取路径时,找不到图像,在创建文件之前记录了 URI,并且能够看到图像文件的正确 URI。现在我在应用程序缓存中创建了一个文件并尝试检索图像的路径然后没有获得完整的图像路径,不确定图像是否已创建,这是我的代码

 val imagesList = data?.extras?.getStringArray(GligarPicker.IMAGES_RESULT)
                if (!imagesList.isNullOrEmpty()) {
                    val arrayList = ArrayList<MultipartBody.Part>()
                    for (i in 0 until imagesList.size) {
                        Log.e("imagesList.item",imagesList[i])
                        val uri = Uri.parse("file://" + imagesList[i].toString())
                        Log.e("URI",uri.toString())
                        val parcelFileDescriptor: ParcelFileDescriptor? =
                            requireContext().contentResolver.openFileDescriptor(uri,"r")
                        val fileDescriptor: FileDescriptor? = parcelFileDescriptor?.fileDescriptor

                        val file = File(
                            requireContext().cacheDir,requireContext().contentResolver.getFileName(uri!!)
                        )
                        Log.e("File",file.path.toString())

                        val inputStream = FileInputStream(fileDescriptor)
                        val outputStream = FileOutputStream(file)
                        inputStream.copyTo(outputStream)

                        // creates RequestBody instance from file

                        val requestFile: RequestBody =
                            RequestBody.create("multipart/form-data".toMediaTypeOrNull(),file)
                        // requireContext().create("multipart/form-data".toMediaTypeOrNull(),file)

                        val body: MultipartBody.Part? =
                            MultipartBody.Part.createFormData("image",file.name,requestFile)

                        if (body != null) {
                            arrayList.add(body)
                        }
                    }

尝试记录 URI 和 FILEPATH ,这是详细信息

URI: file:///storage/emulated/0/DCIM/Camera/IMG_20210131_150237.jpg
File: /data/user/0/com.visilogix.smarttrax/cache

错误日志

  Caused by: java.io.FileNotFoundException: /data/user/0/com.visilogix.smarttrax/cache: open Failed: EISDIR (Is a directory)
    at libcore.io.IoBridge.open(IoBridge.java:496)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:235)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
    at com.visilogix.smarttrax.ui.performputAway.GrnLinesFragment.onActivityResult(GrnLinesFragment.kt:283)
    at androidx.fragment.app.FragmentActivity.onActivityResult(FragmentActivity.java:170)
    at android.app.Activity.dispatchActivityResult(Activity.java:8110)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:4838)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:4886) 
    at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
    at android.os.Handler.dispatchMessage(Handler.java:107) 
    at android.os.Looper.loop(Looper.java:214) 
    at android.app.ActivityThread.main(ActivityThread.java:7356) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 
 Caused by: android.system.ErrnoException: open Failed: EISDIR (Is a directory)
    at libcore.io.Linux.open(Native Method)

更新了创建文件代码

  val uri = Uri.parse("file://" + imagesList[i].toString())
                    Log.e("URI",uri.toString())
                    val parcelFileDescriptor: ParcelFileDescriptor? =
                        requireContext().contentResolver.openFileDescriptor(uri,"r")
                    val fileDescriptor: FileDescriptor? = parcelFileDescriptor?.fileDescriptor

                    val uri1 = Uri.parse(imagesList[i].toString())
                    Log.e("File",requireContext().contentResolver.getFileName(uri1!!))
                    val file = File(
                        requireContext().externalCacheDir?.path,requireContext().contentResolver.getFileName(uri1!!)
                    )
                    file.parentFile.mkdir()
                    file.createNewFile()
                    Log.e(
                        "File2",requireContext().contentResolver.getFileName(uri1!!).toString()
                    )

                    val inputStream = FileInputStream(fileDescriptor)
                    val outputStream = FileOutputStream(file)
                    inputStream.copyTo(outputStream)

应用在 val outputStream = FileOutputStream(file) 崩溃。

 Caused by: java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.visilogix.smarttrax/cache: open Failed: EISDIR (Is a directory)
    at libcore.io.IoBridge.open(IoBridge.java:496)

解决方法

在创建文件时使用“externalCacheDir”而不是“cacheDir”可能会解决问题。

requireContext().externalCacheDir?.let {
            val file = File(
                    it.path,requireContext().contentResolver.getFileName(uri!!)
            )
            file.createNewFile()

        }
,

使用 Okhttp 将图片发送到 php 服务器: 首先将所有图像转换为字节数组并将其放入“backupData”列表中。然后调用“backupOneByOne()”方法。

private var client: OkHttpClient = OkHttpClient()

init {
    client.setReadTimeout(5,TimeUnit.MINUTES)
    client.setConnectTimeout(5,TimeUnit.MINUTES)
}
val backupData: MutableList<ByteArray> = mutableListOf()

private suspend fun backupOneByOne(currentPosition: Int,byteArray: ByteArray) {
    val backupResponse = doBackupMultiPartData("merchantKey",byteArray)

    when (backupResponse) {
        is ResponseResult.Success -> {
            Log.d("nm==>>","Menu Item backup successful !!! AND current item position= $currentPosition")
            if (currentPosition < backupData.size - 1) {
                backupOneByOne(currentPosition + 1,backupData[currentPosition + 1])
            } else {
                Log.d("nm==>>","Backup of all items is done. Current position= $currentPosition")
            }
        }
        is ResponseResult.Error -> {
            Log.d("nm==>>","Error while backup of Advance table : \n ${backupResponse.msg.errorMsg}")
        }
        else -> {
        }
    }
}
suspend fun doBackupMultiPartData(apiKey: String,imageData: ByteArray?): ResponseResult<ResponseWrapper<String>> {
    val requestBody = MultipartBuilder().type(MultipartBuilder.FORM)
    //requestBody.addFormDataPart("id",2) put other form data fields
    if (imageData != null) {
        requestBody.addFormDataPart(
                "file","Logo.png",RequestBody.create(
                MediaType.parse(
                        "image/png"
                ),imageData
        )
        )
    }

    val request = Request.Builder()
            .header("api_key",apiKey) // getting api key from backend
            .url("put url here....")
            .post(requestBody.build())
            .build()
    try {
        val result = apiRequest(request)
        Log.d("nm==>>","Result: $result")
        return if (result != null) {
            val jsonObject = JSONObject(result)
            if (jsonObject.getBoolean("isSuccessful")) {
                ResponseResult.Success(ResponseWrapper("success",null))
            } else {
                ResponseResult.Error(
                        ResponseWrapper(null,"Back end code error: \n $result")
                )
            }
        } else {
            ResponseResult.Error(
                    ResponseWrapper(
                            null,"Getting NULL as result"
                    )
            )
        }
    } catch (jsonException: JSONException) {
        Log.d("nm==>>","Restore JSON exception::: \n ${jsonException.localizedMessage}")
        return ResponseResult.Error(
                ResponseWrapper(
                        null,"Restore Json Exception"
                )
        )
    } catch (exception: Throwable) {
        //Log.d("nm==>>","Network exception::: \n ${exception.localizedMessage}")
        return ResponseResult.NoInternet
    }
}

private suspend fun apiRequest(request: Request): String? = suspendCancellableCoroutine { cancellableContinuation ->
    client.newCall(request).enqueue(object : Callback {
        override fun onFailure(request: Request?,e: IOException?) {
            cancellableContinuation.resumeWith(Result.failure(Throwable("API failed.....${e?.localizedMessage}")))
        }

        override fun onResponse(response: Response?) {
            cancellableContinuation.resumeWith(Result.success(response?.body()?.string()))
        }
    })
}
sealed class ResponseResult<out T> {
    object Loading:ResponseResult<Nothing>()
    object Empty:ResponseResult<Nothing>()
    data class Success<T>(val result:T): ResponseResult<T>()
    data class Error<T>(val msg:T): ResponseResult<T>()
    object NoInternet:ResponseResult<Nothing>()
}
data class ResponseWrapper<out T>(val data: T?,val errorMsg: String?)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。