extractFileToDisk function
Future<void>
extractFileToDisk(
})
Implementation
Future<void> extractFileToDisk(String inputPath, String outputPath,
{String? password, bool asyncWrite = false, int? bufferSize}) async {
Directory? tempDir;
var archivePath = inputPath;
var futures = <Future<void>>[];
if (inputPath.endsWith('tar.gz') || inputPath.endsWith('tgz')) {
tempDir = Directory.systemTemp.createTempSync('dart_archive');
archivePath = path.join(tempDir.path, 'temp.tar');
final input = InputFileStream(inputPath);
final output = OutputFileStream(archivePath, bufferSize: bufferSize);
GZipDecoder().decodeStream(input, output);
futures.add(input.close());
futures.add(output.close());
} else if (inputPath.endsWith('tar.bz2') || inputPath.endsWith('tbz')) {
tempDir = Directory.systemTemp.createTempSync('dart_archive');
archivePath = path.join(tempDir.path, 'temp.tar');
final input = InputFileStream(inputPath);
final output = OutputFileStream(archivePath, bufferSize: bufferSize);
BZip2Decoder().decodeBuffer(input, output: output);
futures.add(input.close());
futures.add(output.close());
} else if (inputPath.endsWith('tar.xz') || inputPath.endsWith('txz')) {
tempDir = Directory.systemTemp.createTempSync('dart_archive');
archivePath = path.join(tempDir.path, 'temp.tar');
final input = InputFileStream(inputPath);
final output = OutputFileStream(archivePath, bufferSize: bufferSize);
output.writeBytes(XZDecoder().decodeBuffer(input));
futures.add(input.close());
futures.add(output.close());
}
if (futures.isNotEmpty) {
await Future.wait(futures);
futures.clear();
}
InputStreamBase? toClose;
Archive archive;
if (archivePath.endsWith('tar')) {
final input = InputFileStream(archivePath);
archive = TarDecoder().decodeBuffer(input);
toClose = input;
} else if (archivePath.endsWith('zip')) {
final input = InputFileStream(archivePath);
archive = ZipDecoder().decodeBuffer(input, password: password);
toClose = input;
} else {
throw ArgumentError.value(inputPath, 'inputPath',
'Must end tar.gz, tgz, tar.bz2, tbz, tar.xz, txz, tar or zip.');
}
for (final file in archive.files) {
final filePath = path.join(outputPath, path.normalize(file.name));
if (!isWithinOutputPath(outputPath, filePath)) {
continue;
}
if (file.isSymbolicLink) {
if (!_isValidSymLink(outputPath, file)) {
continue;
}
}
if (!file.isFile && !file.isSymbolicLink) {
Directory(filePath).createSync(recursive: true);
continue;
}
if (asyncWrite) {
if (file.isSymbolicLink) {
final link = Link(filePath);
await link.create(path.normalize(file.nameOfLinkedFile),
recursive: true);
} else {
final output = File(filePath);
final f = await output.create(recursive: true);
final fp = await f.open(mode: FileMode.write);
final bytes = file.content as List<int>;
await fp.writeFrom(bytes);
file.clear();
futures.add(fp.close());
}
} else {
if (file.isSymbolicLink) {
final link = Link(filePath);
link.createSync(path.normalize(file.nameOfLinkedFile), recursive: true);
} else {
final output = OutputFileStream(filePath, bufferSize: bufferSize);
try {
file.writeContent(output);
} catch (err) {
//
}
futures.add(output.close());
}
}
}
futures.add(toClose.close());
if (futures.isNotEmpty) {
await Future.wait(futures);
futures.clear();
}
futures.add(archive.clear());
if (futures.isNotEmpty) {
await Future.wait(futures);
futures.clear();
}
if (tempDir != null) {
futures.add(tempDir.delete(recursive: true));
}
if (futures.isNotEmpty) {
await Future.wait(futures);
futures.clear();
}
}