private void compress() {
        MappedByteBuffer logFileBuffer;
        try (FileChannel fileChannel = FileChannel.open(currentFile.path(), READ_OPTIONS)) {
            logFileBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
        } catch (Exception e) {
            throw new InputOutputException(
                    "Failed to read the log file: "
                            + currentFile.path(),
                    e);
        }
        FileChannel archiveFileChannel = null;
        Exception exceptionFromCatch = null;
        try {
            try {
                archiveFileChannel =
                        FileChannel.open(currentFile.archivePath(), CREATE_NEW_OPTIONS);
            } catch (FileAlreadyExistsException ignored) {
                return;
            } catch (Exception e) {
                throw new InputOutputException(
                        "Failed to open the archive path: "
                                + currentFile.archivePath(),
                        e);
            }
            try {
                gzipOutputStream.init(archiveFileChannel);
            } catch (Exception e) {
                throw new InputOutputException("Failed to initialize the GZIP output stream", e);
            }
            InputOutputException writeException = null;
            try {
                gzipOutputStream.write(logFileBuffer);
            } catch (Exception e) {
                writeException = new InputOutputException(
                        "Failed to write the log file to the GZIP output stream",
                        e);
                throw writeException;
            } finally {
                try {
                    gzipOutputStream.close();
                } catch (IOException e) {
                    InputOutputException closeException =
                            new InputOutputException("Failed to close the GZIP output stream", e);
                    if (writeException != null) {
                        closeException.addSuppressed(writeException);
                    }
                    throw closeException;
                }
            }
        } catch (Exception e) {
            exceptionFromCatch = e;
            throw e;
        } finally {
            ByteBufferUtil.freeDirectBuffer(logFileBuffer);
            if (archiveFileChannel != null) {
                try {
                    archiveFileChannel.close();
                } catch (IOException e) {
                    InputOutputException closeException =
                            new InputOutputException("Failed to close the archive file channel", e);
                    if (exceptionFromCatch != null) {
                        closeException.addSuppressed(exceptionFromCatch);
                    }
                    throw closeException;
                }
            }
        }
    }
Note that it is fine to close file channel and open a new one not atomically because there is
always only one thread will call roll() and append()
turms-server-common/src/main/java/im/turms/server/common/infra/logging/core/appender/file/RollingFileAppender.java