All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.deephaven.util.channel.LocalFSChannelProvider Maven / Gradle / Ivy

//
// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending
//
package io.deephaven.util.channel;

import io.deephaven.base.FileUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.channels.FileChannel;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.stream.Stream;

public class LocalFSChannelProvider implements SeekableChannelsProvider {
    private static final int MAX_READ_BUFFER_SIZE = 1 << 16; // 64 KiB

    @Override
    public SeekableChannelContext makeContext() {
        // No additional context required for local FS
        return SeekableChannelContext.NULL;
    }

    @Override
    public boolean isCompatibleWith(@Nullable final SeekableChannelContext channelContext) {
        // Context is not used, hence always compatible
        return true;
    }

    @Override
    public SeekableByteChannel getReadChannel(@Nullable final SeekableChannelContext channelContext,
            @NotNull final URI uri)
            throws IOException {
        // context is unused here
        return FileChannel.open(Path.of(uri), StandardOpenOption.READ);
    }

    @Override
    public InputStream getInputStream(final SeekableByteChannel channel, final int sizeHint) {
        // FileChannel is not buffered, need to buffer
        final int bufferSize = Math.min(sizeHint, MAX_READ_BUFFER_SIZE);
        return new BufferedInputStream(Channels.newInputStreamNoClose(channel), bufferSize);
    }

    @Override
    public SeekableByteChannel getWriteChannel(@NotNull final Path filePath, final boolean append) throws IOException {
        final FileChannel result = FileChannel.open(filePath,
                StandardOpenOption.WRITE,
                StandardOpenOption.CREATE,
                append ? StandardOpenOption.APPEND : StandardOpenOption.TRUNCATE_EXISTING);
        if (append) {
            result.position(result.size());
        } else {
            result.position(0);
        }
        return result;
    }

    @Override
    public final Stream list(@NotNull final URI directory) throws IOException {
        // Assuming that the URI is a file, not a directory. The caller should manage file vs. directory handling in
        // the processor.
        return Files.list(Path.of(directory)).map(path -> FileUtils.convertToURI(path, false));
    }

    @Override
    public final Stream walk(@NotNull final URI directory) throws IOException {
        // Assuming that the URI is a file, not a directory. The caller should manage file vs. directory handling in
        // the processor.
        return Files.walk(Path.of(directory)).map(path -> FileUtils.convertToURI(path, false));
    }

    @Override
    public void close() {}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy