org.kitesdk.morphline.hadoop.rcfile.SingleStreamFileSystem.java Source code

Java tutorial

Introduction

Here is the source code for org.kitesdk.morphline.hadoop.rcfile.SingleStreamFileSystem.java

Source

/*
 * Copyright 2013 Cloudera Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.kitesdk.morphline.hadoop.rcfile;

import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;

import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.PositionedReadable;
import org.apache.hadoop.fs.Seekable;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.util.Progressable;

/**
 * Very simple Filesystem Implementation which serves an InputStream for a given
 * path. This is used to serve the underlying input stream from a FileSystem
 * Interface. Only open() and getFileStatus() is implemented.
 */
public final class SingleStreamFileSystem extends FileSystem {
    private final FSDataInputStream inputStream;
    private final Path path;
    private final FileStatus fileStatus;

    public SingleStreamFileSystem(InputStream inputStream, Path path) throws IOException {
        this.inputStream = new FSDataInputStream(new ForwardOnlySeekable(inputStream));
        this.path = path;
        // Since this is a stream, we dont know the length of the stream. Setting it
        // to the maximum size
        this.fileStatus = new FileStatus(Long.MAX_VALUE, false, 0, 0, 0, path);
    }

    @Override
    public URI getUri() {
        throw new UnsupportedOperationException("not implemented!");
    }

    @Override
    public FSDataInputStream open(final Path f, final int bufferSize) throws IOException {
        if (f.equals(path)) {
            return inputStream;
        }
        throw new UnsupportedOperationException("Path " + f.getName() + " is not found");
    }

    @Override
    public FSDataOutputStream create(final Path f, final FsPermission permission, final boolean overwrite,
            final int bufferSize, final short replication, final long blockSize, final Progressable progress)
            throws IOException {
        throw new UnsupportedOperationException("not implemented!");
    }

    @Override
    public FSDataOutputStream append(final Path f, final int bufferSize, final Progressable progress)
            throws IOException {
        throw new UnsupportedOperationException("not implemented!");
    }

    @Override
    public boolean rename(final Path src, final Path dst) throws IOException {
        throw new UnsupportedOperationException("not implemented!");
    }

    @Override
    public boolean delete(final Path f, final boolean recursive) throws IOException {
        throw new UnsupportedOperationException("not implemented!");
    }

    @Override
    public FileStatus[] listStatus(final Path f) throws FileNotFoundException, IOException {
        throw new UnsupportedOperationException("not implemented!");
    }

    @Override
    public void setWorkingDirectory(final Path new_dir) {
        throw new UnsupportedOperationException("not implemented!");
    }

    @Override
    public Path getWorkingDirectory() {
        throw new UnsupportedOperationException("not implemented!");
    }

    @Override
    public boolean mkdirs(final Path f, final FsPermission permission) throws IOException {
        throw new UnsupportedOperationException("not implemented!");
    }

    @Override
    public FileStatus getFileStatus(final Path f) throws IOException {
        if (path.equals(f)) {
            return fileStatus;
        }
        throw new UnsupportedOperationException("Path " + f.getName() + " is not found");
    }

    @Override
    public boolean delete(Path path) throws IOException {
        throw new UnsupportedOperationException("not implemented!");
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Nested classes:
    ///////////////////////////////////////////////////////////////////////////////
    /**
     * Forward-only Seekable InputStream to use for reading SequenceFiles.  Will throw an exception if
     * an attempt is made to seek backwards.
     */
    private static class ForwardOnlySeekable extends InputStream implements Seekable, PositionedReadable {
        private ForwardOnlySeekableInputStream fosInputStream;

        public ForwardOnlySeekable(InputStream inputStream) {
            this.fosInputStream = new ForwardOnlySeekableInputStream(inputStream);
        }

        /**
         * Seek to the given offset from the start of the file.
         * The next read() will be from that location.  Can't
         * seek past the end of the file.
         */
        public void seek(long pos) throws IOException {
            fosInputStream.seek(pos);
        }

        /**
         * Return the current offset from the start of the file
         */
        public long getPos() throws IOException {
            return fosInputStream.tell();
        }

        /**
         * Seeks a different copy of the data.  Returns true if
         * found a new source, false otherwise.
         */
        public boolean seekToNewSource(long targetPos) throws IOException {
            throw new UnsupportedOperationException("not implemented!");
        }

        /**
         * Read upto the specified number of bytes, from a given
         * position within a file, and return the number of bytes read. This does not
         * change the current offset of a file, and is thread-safe.
         */
        public int read(long position, byte[] buffer, int offset, int length) throws IOException {
            throw new UnsupportedOperationException("not implemented!");
        }

        /**
         * Read the specified number of bytes, from a given
         * position within a file. This does not
         * change the current offset of a file, and is thread-safe.
         */
        public void readFully(long position, byte[] buffer, int offset, int length) throws IOException {
            throw new UnsupportedOperationException("not implemented!");
        }

        /**
         * Read number of bytes equal to the length of the buffer, from a given
         * position within a file. This does not
         * change the current offset of a file, and is thread-safe.
         */
        public void readFully(long position, byte[] buffer) throws IOException {
            throw new UnsupportedOperationException("not implemented!");
        }

        public int read() throws IOException {
            byte[] b = new byte[1];
            int len = fosInputStream.read(b, 0, 1);
            int ret = (len == -1) ? -1 : b[0] & 0xFF;
            return ret;
        }
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Nested classes:
    ///////////////////////////////////////////////////////////////////////////////
    /**
     * A SeekableInput backed by an {@link InputStream} that can only advance
     * forward, not backwards.
     */
    private static final class ForwardOnlySeekableInputStream { // implements SeekableInput {

        private final InputStream in;
        private long pos = 0;

        public ForwardOnlySeekableInputStream(InputStream in) {
            this.in = in;
        }

        //    @Override
        public long tell() throws IOException {
            return pos;
        }

        //    @Override
        public int read(byte b[], int off, int len) throws IOException {
            int n = in.read(b, off, len);
            if (n > 0) {
                pos += n;
            }
            return n;
        }

        //    @Override
        public long length() throws IOException {
            throw new UnsupportedOperationException("Random access is not supported");
        }

        //    @Override
        public void seek(long p) throws IOException {
            long todo = p - pos;
            if (todo < 0) {
                throw new UnsupportedOperationException("Seeking backwards is not supported");
            }
            skip(todo);
        }

        private long skip(long len) throws IOException {
            // borrowed from org.apache.hadoop.io.IOUtils.skipFully()
            len = Math.max(0, len);
            long todo = len;
            while (todo > 0) {
                long ret = in.skip(todo);
                if (ret == 0) {
                    // skip may return 0 even if we're not at EOF.  Luckily, we can
                    // use the read() method to figure out if we're at the end.
                    int b = in.read();
                    if (b == -1) {
                        throw new EOFException(
                                "Premature EOF from inputStream after " + "skipping " + (len - todo) + " byte(s).");
                    }
                    ret = 1;
                }
                todo -= ret;
                pos += ret;
            }
            return len;
        }

        //    @Override
        public void close() throws IOException {
            in.close();
        }

    }
}