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