一键导入
file-upload
Load when implementing multipart file upload, download, or file storage. Covers multipart parsing, validation, disk persistence, and URL generation.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Load when implementing multipart file upload, download, or file storage. Covers multipart parsing, validation, disk persistence, and URL generation.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Load when adding scheduled tasks, periodic jobs, or background coroutines. Covers the coroutine-based task pattern, error handling, and lifecycle management.
Load when configuring build pipeline, CI workflows, SonarCloud, JaCoCo, or the Gradle version catalog. Covers fatJar, ktlint, and dependency management.
Load when adding new configuration properties, modifying HOCON files, or understanding how config is loaded. Covers app.conf, application.conf, and the loading pipeline.
IMPORTANT: Load when adding error handling in routes, services, or repositories. Covers AcknowledgeBO vs exceptions, standardized responses, and proper logging.
IMPORTANT: Load when adding monitoring, metrics, or logging. Covers Micrometer/Prometheus, SLF4J usage, CallLogging, and observability patterns.
IMPORTANT: Load when onboarding, planning a new feature, or understanding how the project is wired end-to-end. Covers the full stack: startup → DI → data → routing → config.
| name | file-upload |
| description | Load when implementing multipart file upload, download, or file storage. Covers multipart parsing, validation, disk persistence, and URL generation. |
ImageService)data-accessapi-routingHTTP Multipart Request
↓
call.receiveMultipart() — Ktor multipart stream
↓
getAllParts() — collect all parts (utils/MultipartExtensions.kt)
↓
.filter { contentType startsWith "audio"|"image" } — content type validation
↓
PartData.FileItem — the actual file data (streamProvider, content-type, filename)
↓
File storage service — save to disk, return accessible URL
val multipartData = call.receiveMultipart()
val allParts = multipartData.getAllParts()
val audioFiles = allParts
.filterIsInstance<PartData.FileItem>()
.filter { it.contentType.toString().startsWith("audio") }
// Single file lookup
val singleFile = allParts
.filterIsInstance<PartData.FileItem>()
.find { it.contentType.toString().startsWith("image") }
?: run {
call.respond(HttpStatusCode.UnsupportedMediaType)
return@post
}
getAllParts() extensionLocated in utils/MultipartExtensions.kt:
suspend fun MultiPartData.getAllParts(): List<PartData> = mutableListOf<PartData>().apply {
forEachPart { add(it) }
}.toList()
Use an object (like ImageService) or a Koin single for file operations:
object MyFileService {
private const val EXTENSION = "mp3"
private val storeFolder = config.getString("myFolder")
private val baseUri = config.getString("baseUri")
fun insertFile(id: String, file: PartData.FileItem): String {
val fileName = "$id.$EXTENSION"
val filePath = File("$storeFolder/$id", fileName).normalize()
val inputStream = file.streamProvider.invoke()
if (!filePath.exists()) {
filePath.mkdirs()
}
filePath.writeBytes(inputStream.readBytes())
inputStream.close()
return "$baseUri/files/$id/".normalizeUrl()
}
}
PartData.FileItem — .streamProvider.invoke() gives InputStreamPartData.FileItem — .contentType gives MIME typePartData.FileItem — .originalFileName gives original filenamejava.io.File(...).normalize() to prevent path traversalFile(...).normalize().path.replace("\\", "/") for URL-safe pathsget("/file/{id}") {
val id = call.parameters["id"]
id?.let {
call.respondFile(MyFileService.getFile(id))
}
}
app.conf)Always add storage paths to app.conf:
# Folders are relative to the working directory by default
imageFolder = "images/"
soundFolder = "sounds/"
Access via:
val folder = config.getString("imageFolder")
val baseUri = config.getString("baseUri")
After persisting a file, respond with the generated URL:
val url = service.insertFile(userId, file)
call.respond(HttpStatusCode.OK, url)
streamProvider.invoke() within a use {} block (resource leak)mkdirs()) before writingnormalizeUrl()services/ImageService.kt — reference file upload implementationrouting/UserRouting.kt — multipart usage in routes (images endpoint)routing/SoundRouting.kt — multipart usage for audio uploadutils/MultipartExtensions.kt — getAllParts() helperutils/StringUtils.kt — normalizeUrl()