سعید غفاری
سعید غفاری
خواندن ۳ دقیقه·۴ ماه پیش

دریافت فایل CSV از سرور و انتقال آن به دیتابیس room

توی پست قبلی درباره پشتیبان گیری از دیتابیس محلی حرف زدیم حالا میخوایم فایل csv که آپلود کردیمو و دانلود کنیم و محتویاتشو انتقال بدیم به دیتابیسمون.بریم شروع کنیم.

پیش فرض ما تو این سولوشن استفاده از room و retrofit هست.

قبل از همه چیز این خط رو به فایل build.gradle پروژه اضافه کنید و پروژه رو sync کنید

implementation (&quotcom.opencsv:opencsv:5.5.2&quot)

1- دریافت فایل از سرور:

مثلا ریکوست من این شکلیه:

@GET(&quotbackup/downloadDb&quot) suspend fun downloadDatabase( @Header(&quotAuthorization&quot) token: String? ): Response<ResponseBody>

یه توکن Authorization توی هدر فرستادم و یک جواب گرفتم از نوع ResponseBody

2- بررسی پاسخ و ذخیره فایل دانلود شده:

try {
val token = "your token"
val response = retrofitService.downloadDatabase( token = token)
if (response.isSuccessful) {
response.body()?.let { body ->
val success = saveFile(body)
if (success) {
val filePath = getCsvFilePath()
importCsvToDatabase(filePath)
}
}
}else {
// مدیریت پاسخ ناموفق
}
}catch (e: Exception) {
e.printStackTrace()
}

خب تو این قسمت به ترتیب کارای زیر رو انجام دادیم

  • توکن رو مقدار دهی کردیم
  • فانکشن رتروفیت رو فراخوانی کردیم
  • فایل دانلود شده رو با فانکشن saveFile ذخیره کردیم
  • مسیر فایل ذخیره شده رو به importCsvToDatabase دادیم و فراخوانیش کردیم .

حالا بریم سراغ بقیش.

3-ذخیره فایل دریافتی (فانکشن saveFile):

fun saveFile(body: ResponseBody): Boolean { return try { val file = File(context.filesDir, &quotdownloaded_file.csv&quot) var inputStream: InputStream? = null var outputStream: FileOutputStream? = null try { inputStream = body.byteStream() outputStream = FileOutputStream(file) val buffer = ByteArray(4096) var bytesRead: Int while (inputStream.read(buffer).also { bytesRead = it } != -1) { outputStream.write(buffer, 0, bytesRead) } outputStream.flush() true } finally { inputStream?.close() outputStream?.close() } } catch (e: Exception) { e.printStackTrace() false } }

خب تو این فانکشن فقط به یه توضیح کلی اکتفا کنم اونم اینکه ResponseBody رو دریافت کردیم و اون رو به صورت استریم تو حافظه دستگاه نوشتیمش و بعد در صورتی که عملیات موفق باشه یه مقدار true برمیگردونیم.

4- انتقال محتویات فایل csv به دیتابیس:

fun importCsvToDatabase(csvFilePath:String) { val csvFile=File(csvFilePath) val csvReader = CSVReader(FileReader(csvFile)) val users= mutableListOf<UserEntity>() csvReader.use { reader -> reader.readNext() // خواندن عنوان ستونها var nextLine: Array<String>? while (reader.readNext().also { nextLine = it } != null) { // فرض کنید ستونهای CSV با فیلدهای کلاس Userتطابق دارند val user= User( id = nextLine!![0].toInt(), name = nextLine!![1], phone=nextLine!![2] ) users.add(user) } } yourDao.insertAllUsers(users) }

خب تو این فاکشن با استفاده از کتابخانه ای که implement کردیم فایل csv رو میخونیم و تو حلقه while برای هر ردیف یک آبجکت user میسازیم و اون رو به یک لیست اضافه میکنیم در آخر هم همه لیستمون رو با فانکشنی که تو کلاس dao خودمون داریم ، insert می کنیم توی تیبل user :

@Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertAllUsers(users: List<UserEntity>)


نکته: بهتره یک مدل domain بسازیم که مجزای از entity ما باشه و اول csv رو به مدل domain تبدیل کنیم بعد اون رو مپ کنیم به entity که مربوط به مباحث clean architecture میشه . ولی من تو اینجا مستقیما از entity استفاده کردم .

امیدوارم مفید بوده باشه . ممنون که این مطلب رو مطالعه کردین :)

فایل csv
شاید از این پست‌ها خوشتان بیاید