瀏覽代碼

sample: 新增生成指定大小随机文件上传

drake 1 年之前
父節點
當前提交
486c383e51

二進制
sample/src/main/assets/upload_file.jpg


+ 16 - 1
sample/src/main/java/com/drake/net/sample/mock/MockDispatcher.kt

@@ -4,12 +4,15 @@ import android.util.Log
 import com.drake.engine.base.app
 import com.drake.net.sample.R
 import com.drake.net.sample.constants.Api
+import okhttp3.internal.closeQuietly
 import okhttp3.mockwebserver.Dispatcher
 import okhttp3.mockwebserver.MockResponse
 import okhttp3.mockwebserver.MockWebServer
 import okhttp3.mockwebserver.RecordedRequest
 import okio.buffer
+import okio.sink
 import okio.source
+import java.io.File
 import java.util.concurrent.TimeUnit
 import kotlin.concurrent.thread
 
@@ -37,7 +40,7 @@ class MockDispatcher : Dispatcher() {
         return when (path) {
             Api.TEST -> MockResponse().setHeader("Content-Type", "text/plain").setBody("Request Success : ${request.method}")
             Api.DELAY -> MockResponse().setBodyDelay(2, TimeUnit.SECONDS).setHeader("Content-Type", "text/plain").setBody("Request Success : ${request.method}")
-            Api.UPLOAD -> MockResponse().setBodyDelay(1, TimeUnit.SECONDS).setHeader("Content-Type", "text/plain").setBody("Upload Success")
+            Api.UPLOAD -> uploadFile(request)
             Api.GAME -> getRawResponse(R.raw.game)
             Api.DATA -> getRawResponse(R.raw.data)
             Api.ARRAY -> getRawResponse(R.raw.array)
@@ -47,6 +50,18 @@ class MockDispatcher : Dispatcher() {
         }
     }
 
+    // 将接口上传的文件复制到应用缓存目录
+    private fun uploadFile(req: RecordedRequest): MockResponse {
+        val file = File(app.cacheDir.absolutePath, "uploadFile.apk")
+        val source = req.body
+        file.createNewFile()
+        val sink = file.sink().buffer()
+        sink.writeAll(source)
+        sink.closeQuietly()
+        source.closeQuietly()
+        return MockResponse().setHeader("Content-Type", "text/plain").setBody("Upload success")
+    }
+
     private fun getRawResponse(rawId: Int, delay: Long = 500): MockResponse {
         val buf = app.resources.openRawResource(rawId).source().buffer().readUtf8()
         return MockResponse()

+ 7 - 11
sample/src/main/java/com/drake/net/sample/ui/fragment/UploadFileFragment.kt

@@ -10,11 +10,9 @@ import com.drake.net.sample.R
 import com.drake.net.sample.constants.Api
 import com.drake.net.sample.contract.AlbumSelectContract
 import com.drake.net.sample.databinding.FragmentUploadFileBinding
+import com.drake.net.sample.utils.RandomFileUtils
 import com.drake.net.utils.TipUtils
 import com.drake.net.utils.scopeNetLife
-import okio.buffer
-import okio.sink
-import okio.source
 import java.io.File
 
 
@@ -38,7 +36,7 @@ class UploadFileFragment : EngineFragment<FragmentUploadFileBinding>(R.layout.fr
     private fun uploadFile() {
         scopeNetLife {
             Post<String>(Api.UPLOAD) {
-                param("file", getAssetsFile())
+                param("file", getRandomFile())
                 addUploadListener(object : ProgressListener() {
                     override fun onProgress(p: Progress) {
                         binding.seek.post {
@@ -67,13 +65,11 @@ class UploadFileFragment : EngineFragment<FragmentUploadFileBinding>(R.layout.fr
         }
     }
 
-    private fun getAssetsFile(): File {
-        val fileName = "upload_file.jpg"
-        val inputStream = resources.assets.open(fileName)
-        val file = File(requireContext().filesDir.path, fileName)
-        inputStream.source().buffer().use {
-            it.readAll(file.sink())
-        }
+    /** 生成指定大小的随机文件 */
+    private fun getRandomFile(): File {
+        val file = File(requireContext().filesDir, "uploadFile.apk")
+        // 本演示项目的Mock服务不支持太大的文件, 可能会OOM溢出, 实际接口请求不存在
+        RandomFileUtils.createRandomFile(file, 30, RandomFileUtils.FileSizeUnit.MB)
         return file
     }
 

+ 62 - 0
sample/src/main/java/com/drake/net/sample/utils/RandomFileUtils.kt

@@ -0,0 +1,62 @@
+package com.drake.net.sample.utils
+
+import okhttp3.internal.closeQuietly
+import java.io.File
+import java.io.FileOutputStream
+import java.io.IOException
+import java.nio.ByteBuffer
+
+object RandomFileUtils {
+
+    /**
+     * 创建指定大小随机内容的文件, 创建失败返回false
+     * 如果已经存在指定大小且同名的文件将不再创建
+     */
+    fun createRandomFile(file: File, size: Long, unit: FileSizeUnit): Boolean {
+        val fileLength = unit.getBytes(size)
+        var fos: FileOutputStream? = null
+        try {
+            // 已经存在指定大小且同名的文件结束函数
+            if (!file.createNewFile() && file.length() == fileLength) {
+                return false
+            }
+            var batchSize = fileLength.coerceAtMost(FileSizeUnit.KB.length())
+            batchSize = batchSize.coerceAtMost(FileSizeUnit.MB.length())
+            val count = fileLength / batchSize
+            val last = fileLength % batchSize
+            fos = FileOutputStream(file)
+            val fileChannel = fos.channel
+            for (i in 0 until count) {
+                val buffer = ByteBuffer.allocate(batchSize.toInt())
+                fileChannel.write(buffer)
+            }
+            if (last != 0L) {
+                val buffer = ByteBuffer.allocate(last.toInt())
+                fileChannel.write(buffer)
+            }
+            fos.close()
+            return true
+        } catch (e: IOException) {
+            e.printStackTrace()
+        } finally {
+            fos?.closeQuietly()
+        }
+        return false
+    }
+
+    enum class FileSizeUnit {
+        KB, MB, GB;
+
+        fun getBytes(size: Long): Long {
+            return size * length()
+        }
+
+        fun length(): Long {
+            return when (this) {
+                KB -> 1024
+                MB -> 1024 * 1024
+                GB -> 1024 * 1024 * 1024
+            }
+        }
+    }
+}