magnusja / libaums

Open source library to access USB Mass Storage devices on Android without rooting your device
Apache License 2.0
1.26k stars 270 forks source link

Very low copy speed #401

Open vasiledoe opened 11 months ago

vasiledoe commented 11 months ago

Problem

I need to copy files from USB to device storage, I do it like so:

@Throws(IOException::class)
fun UsbFile.copyTo(outFile: File) {
    var inStream: InputStream? = null
    try {
        inStream = BufferedInputStream(UsbFileInputStream(this))
        val outStream: OutputStream = FileOutputStream(outFile)
        outStream.use {
            inStream.copyTo(it)
            it.close()
        }
    } catch (e: Exception) {
        e.printStackTrace()
    } finally {
        inStream?.close()
    }
}

this kotlin copyTo() method uses default buffer soze: public const val DEFAULT_BUFFER_SIZE: Int = 8 * 1024 (8KB)

This operation takes a lot, especially for big video files. If we increase buffer size like DEFAULT_BUFFER_SIZE * 8 (64KB) then speed will be increased too but this doesn't guarantee that file will be copied successfully. This will work only if Allocation unit size is set >= with this buffer size. There is no way to determine this value from the lib API. Actually we have chunkSize defined in me.jahnen.libaums.core.fs.FileSystem but it always retutns 512

This is where we can change USB Allocation unit size image

Expected behavior

Maybe there is a better/faster way to copy files from USB to internal memory. Maybe there is a way to determine the right value for USB Allocation unit size so we can use it in order to copy faster.

** @magnusja your feedback is appreciated

magnusja commented 9 months ago

Not sure if I understand. You say there should be a faster way to copy but at the same suggest that using larger buffer sizes increases the speed. If the file is corrupt with larger buffer sizes that is a bug in the file system library (maybe?).

The allocation unit size should be the cluster size. So this is also probably a bug if you expect something else with 64 KB.

/**
     * Returns the amount in bytes in one cluster.
     *
     * @return Amount of bytes.
     */
    val bytesPerCluster: Int
        get() = sectorsPerCluster * bytesPerSector
magnusja commented 9 months ago

see also https://github.com/magnusja/libaums/issues/406

junxiaojun commented 9 months ago

@magnusja Thank you. I am very happy to see your reply. The problem has been solved. Thank you very much.