1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
| @Entity @Table(name = "sys_file") interface DataBaseFile : TenantAware { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long
val uid: String
val originalName: String
val type: FileType
val fileData: InputStream }
@Component class FileScalarProvider : ScalarProvider<InputStream, ByteArray> { override fun toScalar(sqlValue: ByteArray): InputStream { val decompress = FileZipUtils.decompress(sqlValue) return ByteArrayInputStream(decompress) }
override fun toSql(scalarValue: InputStream): ByteArray { val compress = FileZipUtils.compress(scalarValue.readAllBytes()) return compress } }
@ConditionalOnProperty(prefix = "file", name = ["storage"], havingValue = "database") @Service class DataBaseFileService( private val dataBaseFileRepository: DataBaseFileRepository, ) : FileService {
override fun uploadFile(multipartFile: MultipartFile): String { if (multipartFile.size > 0) {
val baseFile = new(DataBaseFile::class).by { this.uid = UUID.randomUUID().toString() this.originalName = multipartFile.originalFilename ?: UUID.randomUUID().toString() this.type = getFileType(multipartFile) this.fileData = ByteArrayInputStream(multipartFile.bytes) } dataBaseFileRepository.insert(baseFile) return baseFile.uid } throw EmptyFileException("文件不能为空") }
override fun getFile(fileName: String): Pair<String, ByteArrayInputStream> { val dataBaseFile = dataBaseFileRepository.findByUid(fileName) return dataBaseFile.originalName to ByteArrayInputStream(dataBaseFile.fileData.readAllBytes()) } }
object FileZipUtils { const val BITE_SIZE: Int = 4 * 1024 fun compress(data: ByteArray): ByteArray { val deflater = Deflater() deflater.setLevel(Deflater.BEST_COMPRESSION) deflater.setInput(data) deflater.finish() val outputStream = ByteArrayOutputStream(data.size) val tmp = ByteArray(BITE_SIZE)
while (!deflater.finished()) { val size = deflater.deflate(tmp) outputStream.write(tmp, 0, size) }
outputStream.close()
return outputStream.toByteArray() }
fun decompress(data: ByteArray): ByteArray { val inflater = Inflater() inflater.setInput(data) val outputStream = ByteArrayOutputStream(data.size) val tmp = ByteArray(BITE_SIZE)
while (!inflater.finished()) { val count = inflater.inflate(tmp) outputStream.write(tmp, 0, count) }
outputStream.close()
return outputStream.toByteArray() } }
@PostMapping(path = ["/upload/file"], consumes = [MediaType.MULTIPART_FORM_DATA_VALUE]) fun uploadFile( @RequestParam("file") file: MultipartFile, ): R<String> { val uploadImage = this.fileService.uploadFile(file) return R.success(data = uploadImage) }
@GetMapping("/download/file") fun downloadFile( @RequestParam(name = "uid") uid: String, request: HttpServletRequest, response: HttpServletResponse, ) { val data = this.fileService.getFile(uid) writeFileToResponse(data.first, data.second, request, response) }
fun writeFileToResponse( fileName: String, stream: InputStream, request: HttpServletRequest, response: HttpServletResponse, ) { val readAllBytes = stream.readAllBytes() response.contentType = "application/octet-stream" response.setHeader("Content-Disposition", "attachment; filename=\"$fileName\"") response.setContentLength(readAllBytes.size) val servletOutputStream: OutputStream = response.outputStream servletOutputStream.write(readAllBytes) servletOutputStream.flush() }
|