mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-16 23:37:14 -04:00
parent
68dbe6945b
commit
24fd2cf521
@ -35,17 +35,15 @@ import org.jackhuang.hmcl.upgrade.UpdateHandler;
|
|||||||
import org.jackhuang.hmcl.util.StringUtils;
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
import org.jackhuang.hmcl.util.i18n.Locales;
|
import org.jackhuang.hmcl.util.i18n.Locales;
|
||||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||||
|
import org.jackhuang.hmcl.util.io.IOUtils;
|
||||||
import org.tukaani.xz.XZInputStream;
|
import org.tukaani.xz.XZInputStream;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.channels.Channels;
|
|
||||||
import java.nio.channels.FileChannel;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.StandardOpenOption;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -132,6 +130,42 @@ public final class SettingsPage extends SettingsView {
|
|||||||
UpdateHandler.updateFrom(target);
|
UpdateHandler.updateFrom(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This method guarantees to close both `input` and the current zip entry.
|
||||||
|
///
|
||||||
|
/// If no exception occurs, this method returns `true`;
|
||||||
|
/// If an exception occurs while reading from `input`, this method returns `false`;
|
||||||
|
/// If an exception occurs while writing to `output`, this method will throw it as is.
|
||||||
|
private static boolean exportLogFile(ZipOutputStream output,
|
||||||
|
Path file, // For logging
|
||||||
|
String entryName,
|
||||||
|
InputStream input,
|
||||||
|
byte[] buffer) throws IOException {
|
||||||
|
//noinspection TryFinallyCanBeTryWithResources
|
||||||
|
try {
|
||||||
|
output.putNextEntry(new ZipEntry(entryName));
|
||||||
|
int read;
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
read = input.read(buffer);
|
||||||
|
if (read <= 0)
|
||||||
|
return true;
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
LOG.warning("Failed to decompress log file " + file, ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
output.write(buffer, 0, read);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
input.close();
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
LOG.warning("Failed to close log file " + file, ex);
|
||||||
|
}
|
||||||
|
output.closeEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onExportLogs() {
|
protected void onExportLogs() {
|
||||||
thread(() -> {
|
thread(() -> {
|
||||||
@ -152,45 +186,54 @@ public final class SettingsPage extends SettingsView {
|
|||||||
|
|
||||||
LOG.info("Exporting latest logs to " + outputFile);
|
LOG.info("Exporting latest logs to " + outputFile);
|
||||||
|
|
||||||
Path tempFile = Files.createTempFile("hmcl-decompress-log-", ".txt");
|
byte[] buffer = new byte[IOUtils.DEFAULT_BUFFER_SIZE];
|
||||||
try (var tempChannel = FileChannel.open(tempFile, StandardOpenOption.READ, StandardOpenOption.WRITE);
|
try (var os = Files.newOutputStream(outputFile);
|
||||||
var os = Files.newOutputStream(outputFile);
|
|
||||||
var zos = new ZipOutputStream(os)) {
|
var zos = new ZipOutputStream(os)) {
|
||||||
|
|
||||||
for (Path path : recentLogFiles) {
|
for (Path path : recentLogFiles) {
|
||||||
String extension = FileUtils.getExtension(path);
|
String fileName = FileUtils.getName(path);
|
||||||
decompress:
|
String extension = StringUtils.substringAfterLast(fileName, '.');
|
||||||
if ("gz".equalsIgnoreCase(extension) || "xz".equalsIgnoreCase(extension)) {
|
|
||||||
try (InputStream fis = Files.newInputStream(path);
|
if ("gz".equals(extension) || "xz".equals(extension)) {
|
||||||
InputStream uncompressed = "gz".equalsIgnoreCase(extension)
|
// If an exception occurs while decompressing the input file, we should
|
||||||
? new GZIPInputStream(fis)
|
// ensure the input file and the current zip entry are closed,
|
||||||
: new XZInputStream(fis)) {
|
// then copy the compressed file content as-is into a new entry in the zip file.
|
||||||
uncompressed.transferTo(Channels.newOutputStream(tempChannel));
|
|
||||||
} catch (IOException e) {
|
InputStream input = null;
|
||||||
LOG.warning("Failed to decompress log: " + path, e);
|
try {
|
||||||
break decompress;
|
input = Files.newInputStream(path);
|
||||||
|
input = "gz".equals(extension)
|
||||||
|
? new GZIPInputStream(input)
|
||||||
|
: new XZInputStream(input);
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
LOG.warning("Failed to open log file " + path, ex);
|
||||||
|
IOUtils.closeQuietly(input, ex);
|
||||||
|
input = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
zos.putNextEntry(new ZipEntry(StringUtils.substringBeforeLast(FileUtils.getName(path), '.')));
|
String entryName = StringUtils.substringBeforeLast(fileName, ".");
|
||||||
Channels.newInputStream(tempChannel).transferTo(zos);
|
if (input != null && exportLogFile(zos, path, entryName, input, buffer))
|
||||||
zos.closeEntry();
|
continue;
|
||||||
tempChannel.truncate(0);
|
}
|
||||||
|
|
||||||
|
// Copy the log file content as-is into a new entry in the zip file.
|
||||||
|
// If an exception occurs while decompressing the input file, we should
|
||||||
|
// ensure the input file and the current zip entry are closed.
|
||||||
|
|
||||||
|
InputStream input;
|
||||||
|
try {
|
||||||
|
input = Files.newInputStream(path);
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
LOG.warning("Failed to open log file " + path, ex);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
zos.putNextEntry(new ZipEntry(FileUtils.getName(path)));
|
exportLogFile(zos, path, fileName, input, buffer);
|
||||||
Files.copy(path, zos);
|
|
||||||
zos.closeEntry();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zos.putNextEntry(new ZipEntry("hmcl-latest.log"));
|
zos.putNextEntry(new ZipEntry("hmcl-latest.log"));
|
||||||
LOG.exportLogs(zos);
|
LOG.exportLogs(zos);
|
||||||
zos.closeEntry();
|
zos.closeEntry();
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
Files.deleteIfExists(tempFile);
|
|
||||||
} catch (IOException ignored) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user