Properly buffer I/O

This commit is contained in:
topjohnwu 2025-03-20 13:16:39 -07:00
parent f56fd4e215
commit 6f90456036

View File

@ -46,7 +46,6 @@ import java.io.OutputStream
import java.io.PushbackInputStream
import java.nio.ByteBuffer
import java.security.SecureRandom
import java.util.Arrays
import java.util.Locale
import java.util.concurrent.atomic.AtomicBoolean
@ -190,7 +189,8 @@ abstract class MagiskInstallImpl protected constructor(
return true
}
private suspend fun InputStream.copyAndCloseOut(out: OutputStream) = out.use { copyAll(it) }
private suspend fun InputStream.copyAndCloseOut(out: OutputStream) =
out.use { copyAll(it, 1024 * 1024) }
private class NoAvailableStream(s: InputStream) : FilterInputStream(s) {
// Make sure available is never called on the actual stream and always return 0
@ -224,8 +224,8 @@ abstract class MagiskInstallImpl protected constructor(
console.add("- Processing tar file")
var entry: TarArchiveEntry? = tarIn.nextEntry
fun TarArchiveEntry.decompressedStream(): InputStream {
val stream = if (name.endsWith(".lz4"))
fun decompressedStream(): InputStream {
val stream = if (tarIn.currentEntry.name.endsWith(".lz4"))
FramedLZ4CompressorInputStream(tarIn, true) else tarIn
return NoAvailableStream(stream)
}
@ -251,9 +251,9 @@ abstract class MagiskInstallImpl protected constructor(
if (bootItem != null) {
console.add("-- Extracting: ${bootItem.name}")
entry.decompressedStream().copyAndCloseOut(bootItem.file.newOutputStream())
decompressedStream().copyAndCloseOut(bootItem.file.newOutputStream())
} else if (entry.name.contains("vbmeta.img")) {
val rawData = entry.decompressedStream().readBytes()
val rawData = decompressedStream().readBytes()
// Valid vbmeta.img should be at least 256 bytes
if (rawData.size < 256)
continue
@ -286,7 +286,7 @@ abstract class MagiskInstallImpl protected constructor(
} else {
console.add("-- Copying : ${entry.name}")
tarOut.putArchiveEntry(entry)
tarIn.copyAll(tarOut, bufferSize = 1024 * 1024)
tarIn.copyAll(tarOut)
tarOut.closeArchiveEntry()
}
entry = tarIn.nextEntry ?: break
@ -428,7 +428,7 @@ abstract class MagiskInstallImpl protected constructor(
// Process input file
try {
PushbackInputStream(uri.inputStream(), 512).use { src ->
PushbackInputStream(uri.inputStream().buffered(1024 * 1024), 512).use { src ->
val head = ByteArray(512)
if (src.read(head) != head.size) {
console.add("! Invalid input file")
@ -437,12 +437,13 @@ abstract class MagiskInstallImpl protected constructor(
src.unread(head)
val magic = head.copyOf(4)
val tarMagic = Arrays.copyOfRange(head, 257, 262)
val tarMagic = head.copyOfRange(257, 262)
srcBoot = if (tarMagic.contentEquals("ustar".toByteArray())) {
// tar file
outFile = MediaStoreUtils.getFile("$destName.tar")
outStream = TarArchiveOutputStream(outFile.uri.outputStream()).also {
val os = outFile.uri.outputStream().buffered(1024 * 1024)
outStream = TarArchiveOutputStream(os).also {
it.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR)
it.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU)
}
@ -499,7 +500,7 @@ abstract class MagiskInstallImpl protected constructor(
bootItem.file = newBoot
bootItem.copyTo(outStream as TarArchiveOutputStream)
} else {
newBoot.newInputStream().use { it.copyAll(outStream) }
newBoot.newInputStream().use { it.copyAll(outStream, 1024 * 1024) }
}
newBoot.delete()