using temp file for stream conversion
This commit is contained in:
parent
03778784bc
commit
de0a5be100
|
@ -0,0 +1,27 @@
|
|||
package org.mariotaku.twidere.util
|
||||
|
||||
import android.support.test.InstrumentationRegistry
|
||||
import android.support.test.runner.AndroidJUnit4
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/1/24.
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class IOFunctionsKtTest {
|
||||
@Test
|
||||
fun testTempFileInputStream() {
|
||||
val context = InstrumentationRegistry.getTargetContext()
|
||||
val random = Random()
|
||||
val testData = ByteArray(1024)
|
||||
random.nextBytes(testData)
|
||||
val compareData = tempFileInputStream(context) { os ->
|
||||
os.write(testData)
|
||||
}.readBytes(1024)
|
||||
Assert.assertArrayEquals(testData, compareData)
|
||||
}
|
||||
|
||||
}
|
|
@ -8,8 +8,8 @@ import org.mariotaku.twidere.extension.model.filename
|
|||
import org.mariotaku.twidere.extension.model.readMimeMessageFrom
|
||||
import org.mariotaku.twidere.extension.model.writeMimeMessageTo
|
||||
import org.mariotaku.twidere.model.Draft
|
||||
import org.mariotaku.twidere.util.io.DirectByteArrayOutputStream
|
||||
import org.mariotaku.twidere.util.sync.FileBasedDraftsSyncAction
|
||||
import org.mariotaku.twidere.util.tempFileInputStream
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
|
||||
|
@ -27,20 +27,21 @@ internal class GoogleDriveDraftsSyncAction(
|
|||
|
||||
@Throws(IOException::class)
|
||||
override fun Draft.saveToRemote(): DriveFileInfo {
|
||||
val os = DirectByteArrayOutputStream()
|
||||
this.writeMimeMessageTo(context, os)
|
||||
val driveId = this.remote_extras
|
||||
val `is` = os.inputStream(true)
|
||||
val fileConfig: (File) -> Unit = {
|
||||
it.modifiedTime = DateTime(timestamp)
|
||||
tempFileInputStream(context) { os ->
|
||||
this.writeMimeMessageTo(context, os)
|
||||
}.use {
|
||||
val driveId = this.remote_extras
|
||||
val fileConfig: (File) -> Unit = {
|
||||
it.modifiedTime = DateTime(timestamp)
|
||||
}
|
||||
val file = if (driveId != null) {
|
||||
drive.files().performUpdate(driveId, filename, draftMimeType, stream = it, fileConfig = fileConfig)
|
||||
} else {
|
||||
drive.updateOrCreate(name = filename, mimeType = draftMimeType, parent = folderId,
|
||||
spaces = appDataFolderSpace, stream = it, fileConfig = fileConfig)
|
||||
}
|
||||
return DriveFileInfo(file.id, file.name, Date(file.modifiedTime.value))
|
||||
}
|
||||
val file = if (driveId != null) {
|
||||
drive.files().performUpdate(driveId, filename, draftMimeType, stream = `is`, fileConfig = fileConfig)
|
||||
} else {
|
||||
drive.updateOrCreate(name = filename, mimeType = draftMimeType, parent = folderId,
|
||||
spaces = appDataFolderSpace, stream = `is`, fileConfig = fileConfig)
|
||||
}
|
||||
return DriveFileInfo(file.id, file.name, Date(file.modifiedTime.value))
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
|
|
|
@ -9,8 +9,8 @@ import org.mariotaku.twidere.extension.model.serialize
|
|||
import org.mariotaku.twidere.extension.newPullParser
|
||||
import org.mariotaku.twidere.extension.newSerializer
|
||||
import org.mariotaku.twidere.model.FiltersData
|
||||
import org.mariotaku.twidere.util.io.DirectByteArrayOutputStream
|
||||
import org.mariotaku.twidere.util.sync.FileBasedFiltersDataSyncAction
|
||||
import org.mariotaku.twidere.util.tempFileInputStream
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
@ -56,9 +56,9 @@ internal class GoogleDriveFiltersDataSyncAction(
|
|||
override fun newSaveToRemoteSession(): GoogleDriveUploadSession<FiltersData> {
|
||||
return object : GoogleDriveUploadSession<FiltersData>(fileName, commonFolderId, xmlMimeType, drive) {
|
||||
override fun FiltersData.toInputStream(): InputStream {
|
||||
val os = DirectByteArrayOutputStream()
|
||||
this.serialize(os.newSerializer(charset = Charsets.UTF_8, indent = true))
|
||||
return os.inputStream(true)
|
||||
return tempFileInputStream(context) {
|
||||
this.serialize(it.newSerializer(charset = Charsets.UTF_8, indent = true))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ import com.google.api.services.drive.Drive
|
|||
import com.google.api.services.drive.model.File
|
||||
import org.mariotaku.twidere.extension.newPullParser
|
||||
import org.mariotaku.twidere.extension.newSerializer
|
||||
import org.mariotaku.twidere.util.io.DirectByteArrayOutputStream
|
||||
import org.mariotaku.twidere.util.sync.FileBasedPreferencesValuesSyncAction
|
||||
import org.mariotaku.twidere.util.tempFileInputStream
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
@ -48,9 +48,9 @@ internal class GoogleDrivePreferencesValuesSyncAction(
|
|||
override fun newSaveToRemoteSession(): GoogleDriveUploadSession<Map<String, String>> {
|
||||
return object : GoogleDriveUploadSession<Map<String, String>>(fileName, commonFolderId, xmlMimeType, drive) {
|
||||
override fun Map<String, String>.toInputStream(): InputStream {
|
||||
val os = DirectByteArrayOutputStream()
|
||||
this.serialize(os.newSerializer(charset = Charsets.UTF_8, indent = true))
|
||||
return os.inputStream(true)
|
||||
return tempFileInputStream(context) {
|
||||
this.serialize(it.newSerializer(charset = Charsets.UTF_8, indent = true))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,12 @@ abstract internal class GoogleDriveUploadSession<in Data>(
|
|||
abstract fun Data.toInputStream(): InputStream
|
||||
|
||||
fun uploadData(data: Data): Boolean {
|
||||
drive.updateOrCreate(name = name, mimeType = mimeType, parent = parentId,
|
||||
spaces = appDataFolderSpace, stream = data.toInputStream(), fileConfig = {
|
||||
it.modifiedTime = DateTime(localModifiedTime)
|
||||
})
|
||||
data.toInputStream().use {
|
||||
drive.updateOrCreate(name = name, mimeType = mimeType, parent = parentId,
|
||||
spaces = appDataFolderSpace, stream = it, fileConfig = {
|
||||
it.modifiedTime = DateTime(localModifiedTime)
|
||||
})
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -43,12 +43,8 @@ import org.mariotaku.twidere.model.UserKey
|
|||
import org.mariotaku.twidere.model.util.AccountUtils
|
||||
import org.mariotaku.twidere.model.util.ParcelableStatusUtils
|
||||
import org.mariotaku.twidere.task.twitter.GetStatusesTask
|
||||
import org.mariotaku.twidere.util.JsonSerializer
|
||||
import org.mariotaku.twidere.util.SharedPreferencesWrapper
|
||||
import org.mariotaku.twidere.util.TwidereArrayUtils
|
||||
import org.mariotaku.twidere.util.UserColorNameManager
|
||||
import org.mariotaku.twidere.util.*
|
||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
|
@ -237,10 +233,9 @@ abstract class MicroBlogAPIStatusesLoader(
|
|||
val databaseItemLimit = preferences[loadItemLimitKey]
|
||||
try {
|
||||
val statuses = data.subList(0, Math.min(databaseItemLimit, data.size))
|
||||
fileCache.save(key, ByteArrayInputStream(byteArrayOf())) { current, total -> true }
|
||||
fileCache.get(key)?.outputStream()?.use {
|
||||
LoganSquare.serialize(statuses, it, ParcelableStatus::class.java)
|
||||
}
|
||||
fileCache.save(key, tempFileInputStream(context) { os ->
|
||||
LoganSquare.serialize(statuses, os, ParcelableStatus::class.java)
|
||||
}) { current, total -> true }
|
||||
} catch (e: Exception) {
|
||||
// Ignore
|
||||
if (BuildConfig.DEBUG && e !is IOException) {
|
||||
|
|
|
@ -259,7 +259,13 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") {
|
|||
val exception = result.exception
|
||||
val exceptions = result.exceptions
|
||||
if (exception != null) {
|
||||
Toast.makeText(context, exception.message, Toast.LENGTH_SHORT).show()
|
||||
val cause = exception.cause
|
||||
if (cause is MicroBlogException) {
|
||||
Toast.makeText(context, cause.errors?.firstOrNull()?.message ?: cause.message,
|
||||
Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Toast.makeText(context, exception.message, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
failed = true
|
||||
Log.w(LOGTAG, exception)
|
||||
} else for (e in exceptions) {
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package org.mariotaku.twidere.util
|
||||
|
||||
import android.content.Context
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 2017/1/24.
|
||||
*/
|
||||
|
||||
fun tempFileInputStream(context: Context, write: (OutputStream) -> Unit): InputStream {
|
||||
val file = File.createTempFile("twidere__temp_is_file", "tmp", context.cacheDir)
|
||||
file.outputStream().use { write(it) }
|
||||
return TempFileInputStream(file)
|
||||
}
|
||||
|
||||
internal class TempFileInputStream(val file: File) : FileInputStream(file) {
|
||||
override fun close() {
|
||||
try {
|
||||
super.close()
|
||||
} finally {
|
||||
file.delete()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package org.mariotaku.twidere.util.io
|
||||
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.InputStream
|
||||
|
||||
class DirectByteArrayOutputStream : ByteArrayOutputStream() {
|
||||
|
||||
fun inputStream(close: Boolean): InputStream {
|
||||
return DirectInputStream(this, close)
|
||||
}
|
||||
|
||||
internal class DirectInputStream(
|
||||
val os: DirectByteArrayOutputStream,
|
||||
val close: Boolean
|
||||
) : ByteArrayInputStream(os.buf, 0, os.count) {
|
||||
override fun close() {
|
||||
if (close) {
|
||||
os.close()
|
||||
}
|
||||
super.close()
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue