EventLogDirectory.java

net.minecraft.util.eventlog.EventLogDirectory

信息

  • 全限定名:net.minecraft.util.eventlog.EventLogDirectory
  • 类型:public class
  • 包:net.minecraft.util.eventlog
  • 源码路径:src/main/java/net/minecraft/util/eventlog/EventLogDirectory.java
  • 起始行号:L33
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L34
    • 说明:

      TODO

  • COMPRESS_BUFFER_SIZE

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L35
    • 说明:

      TODO

  • COMPRESSED_EXTENSION

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L36
    • 说明:

      TODO

  • root

    • 类型: Path
    • 修饰符: private final
    • 源码定位: L37
    • 说明:

      TODO

  • extension

    • 类型: String
    • 修饰符: private final
    • 源码定位: L38
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.util.eventlog.EventLogDirectory.CompressedFile

    • 类型: record
    • 修饰符: public
    • 源码定位: L126
    • 说明:

      TODO

  • net.minecraft.util.eventlog.EventLogDirectory.File

    • 类型: interface
    • 修饰符: public
    • 源码定位: L140
    • 说明:

      TODO

  • net.minecraft.util.eventlog.EventLogDirectory.FileId

    • 类型: record
    • 修饰符: public
    • 源码定位: L150
    • 说明:

      TODO

  • net.minecraft.util.eventlog.EventLogDirectory.FileList

    • 类型: class
    • 修饰符: public static
    • 源码定位: L179
    • 说明:

      TODO

  • net.minecraft.util.eventlog.EventLogDirectory.RawFile

    • 类型: record
    • 修饰符: public
    • 源码定位: L234
    • 说明:

      TODO

构造器

private EventLogDirectory(Path root, String extension) @ L40

  • 构造器名:EventLogDirectory
  • 源码定位:L40
  • 修饰符:private

参数:

  • root: Path
  • extension: String

说明:

TODO

方法

下面的方法块按源码顺序生成。

public static EventLogDirectory open(Path root, String extension) @ L45

  • 方法名:open
  • 源码定位:L45
  • 返回类型:EventLogDirectory
  • 修饰符:public static

参数:

  • root: Path
  • extension: String

说明:

TODO

public EventLogDirectory.FileList listFiles() @ L50

  • 方法名:listFiles
  • 源码定位:L50
  • 返回类型:EventLogDirectory.FileList
  • 修饰符:public

参数:

说明:

TODO

private EventLogDirectory.File parseFile(Path path) @ L59

  • 方法名:parseFile
  • 源码定位:L59
  • 返回类型:EventLogDirectory.File
  • 修饰符:private

参数:

  • path: Path

说明:

TODO

private static void tryCompress(Path raw, Path compressed) @ L81

  • 方法名:tryCompress
  • 源码定位:L81
  • 返回类型:void
  • 修饰符:private static

参数:

  • raw: Path
  • compressed: Path

说明:

TODO

private static void writeCompressed(ReadableByteChannel channel, Path target) @ L99

  • 方法名:writeCompressed
  • 源码定位:L99
  • 返回类型:void
  • 修饰符:private static

参数:

  • channel: ReadableByteChannel
  • target: Path

说明:

TODO

public EventLogDirectory.RawFile createNewFile(LocalDate date) @ L112

  • 方法名:createNewFile
  • 源码定位:L112
  • 返回类型:EventLogDirectory.RawFile
  • 修饰符:public

参数:

  • date: LocalDate

说明:

TODO

代码

public class EventLogDirectory {
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final int COMPRESS_BUFFER_SIZE = 4096;
    private static final String COMPRESSED_EXTENSION = ".gz";
    private final Path root;
    private final String extension;
 
    private EventLogDirectory(Path root, String extension) {
        this.root = root;
        this.extension = extension;
    }
 
    public static EventLogDirectory open(Path root, String extension) throws IOException {
        Files.createDirectories(root);
        return new EventLogDirectory(root, extension);
    }
 
    public EventLogDirectory.FileList listFiles() throws IOException {
        EventLogDirectory.FileList var2;
        try (Stream<Path> list = Files.list(this.root)) {
            var2 = new EventLogDirectory.FileList(list.filter(x$0 -> Files.isRegularFile(x$0)).map(this::parseFile).filter(Objects::nonNull).toList());
        }
 
        return var2;
    }
 
    private EventLogDirectory.@Nullable File parseFile(Path path) {
        String fileName = path.getFileName().toString();
        int extensionIndex = fileName.indexOf(46);
        if (extensionIndex == -1) {
            return null;
        } else {
            EventLogDirectory.FileId id = EventLogDirectory.FileId.parse(fileName.substring(0, extensionIndex));
            if (id != null) {
                String extension = fileName.substring(extensionIndex);
                if (extension.equals(this.extension)) {
                    return new EventLogDirectory.RawFile(path, id);
                }
 
                if (extension.equals(this.extension + ".gz")) {
                    return new EventLogDirectory.CompressedFile(path, id);
                }
            }
 
            return null;
        }
    }
 
    private static void tryCompress(Path raw, Path compressed) throws IOException {
        if (Files.exists(compressed)) {
            throw new IOException("Compressed target file already exists: " + compressed);
        } else {
            try (FileChannel channel = FileChannel.open(raw, StandardOpenOption.WRITE, StandardOpenOption.READ)) {
                FileLock lock = channel.tryLock();
                if (lock == null) {
                    throw new IOException("Raw log file is already locked, cannot compress: " + raw);
                }
 
                writeCompressed(channel, compressed);
                channel.truncate(0L);
            }
 
            Files.delete(raw);
        }
    }
 
    private static void writeCompressed(ReadableByteChannel channel, Path target) throws IOException {
        try (OutputStream output = new GZIPOutputStream(Files.newOutputStream(target))) {
            byte[] bytes = new byte[4096];
            ByteBuffer buffer = ByteBuffer.wrap(bytes);
 
            while (channel.read(buffer) >= 0) {
                buffer.flip();
                output.write(bytes, 0, buffer.limit());
                buffer.clear();
            }
        }
    }
 
    public EventLogDirectory.RawFile createNewFile(LocalDate date) throws IOException {
        int index = 1;
        Set<EventLogDirectory.FileId> files = this.listFiles().ids();
 
        EventLogDirectory.FileId id;
        do {
            id = new EventLogDirectory.FileId(date, index++);
        } while (files.contains(id));
 
        EventLogDirectory.RawFile file = new EventLogDirectory.RawFile(this.root.resolve(id.toFileName(this.extension)), id);
        Files.createFile(file.path());
        return file;
    }
 
    public record CompressedFile(Path path, EventLogDirectory.FileId id) implements EventLogDirectory.File {
        @Override
        public @Nullable Reader openReader() throws IOException {
            return !Files.exists(this.path)
                ? null
                : new BufferedReader(new InputStreamReader(new GZIPInputStream(Files.newInputStream(this.path)), StandardCharsets.UTF_8));
        }
 
        @Override
        public EventLogDirectory.CompressedFile compress() {
            return this;
        }
    }
 
    public interface File {
        Path path();
 
        EventLogDirectory.FileId id();
 
        @Nullable Reader openReader() throws IOException;
 
        EventLogDirectory.CompressedFile compress() throws IOException;
    }
 
    public record FileId(LocalDate date, int index) {
        private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.BASIC_ISO_DATE;
 
        public static EventLogDirectory.@Nullable FileId parse(String name) {
            int separator = name.indexOf("-");
            if (separator == -1) {
                return null;
            } else {
                String date = name.substring(0, separator);
                String index = name.substring(separator + 1);
 
                try {
                    return new EventLogDirectory.FileId(LocalDate.parse(date, DATE_FORMATTER), Integer.parseInt(index));
                } catch (DateTimeParseException | NumberFormatException var5) {
                    return null;
                }
            }
        }
 
        @Override
        public String toString() {
            return DATE_FORMATTER.format(this.date) + "-" + this.index;
        }
 
        public String toFileName(String extension) {
            return this + extension;
        }
    }
 
    public static class FileList implements Iterable<EventLogDirectory.File> {
        private final List<EventLogDirectory.File> files;
 
        private FileList(List<EventLogDirectory.File> files) {
            this.files = new ArrayList<>(files);
        }
 
        public EventLogDirectory.FileList prune(LocalDate date, int expiryDays) {
            this.files.removeIf(file -> {
                EventLogDirectory.FileId id = file.id();
                LocalDate expiresAt = id.date().plusDays(expiryDays);
                if (!date.isBefore(expiresAt)) {
                    try {
                        Files.delete(file.path());
                        return true;
                    } catch (IOException var6) {
                        EventLogDirectory.LOGGER.warn("Failed to delete expired event log file: {}", file.path(), var6);
                    }
                }
 
                return false;
            });
            return this;
        }
 
        public EventLogDirectory.FileList compressAll() {
            ListIterator<EventLogDirectory.File> iterator = this.files.listIterator();
 
            while (iterator.hasNext()) {
                EventLogDirectory.File file = iterator.next();
 
                try {
                    iterator.set(file.compress());
                } catch (IOException var4) {
                    EventLogDirectory.LOGGER.warn("Failed to compress event log file: {}", file.path(), var4);
                }
            }
 
            return this;
        }
 
        @Override
        public Iterator<EventLogDirectory.File> iterator() {
            return this.files.iterator();
        }
 
        public Stream<EventLogDirectory.File> stream() {
            return this.files.stream();
        }
 
        public Set<EventLogDirectory.FileId> ids() {
            return this.files.stream().map(EventLogDirectory.File::id).collect(Collectors.toSet());
        }
    }
 
    public record RawFile(Path path, EventLogDirectory.FileId id) implements EventLogDirectory.File {
        public FileChannel openChannel() throws IOException {
            return FileChannel.open(this.path, StandardOpenOption.WRITE, StandardOpenOption.READ);
        }
 
        @Override
        public @Nullable Reader openReader() throws IOException {
            return Files.exists(this.path) ? Files.newBufferedReader(this.path) : null;
        }
 
        @Override
        public EventLogDirectory.CompressedFile compress() throws IOException {
            Path compressedPath = this.path.resolveSibling(this.path.getFileName().toString() + ".gz");
            EventLogDirectory.tryCompress(this.path, compressedPath);
            return new EventLogDirectory.CompressedFile(compressedPath, this.id);
        }
    }
}

引用的其他类