Package org.rzo.yajsw.io

Source Code of org.rzo.yajsw.io.CyclicBufferFileInputStream

/* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* <p/>
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details. 
*/
package org.rzo.yajsw.io;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.rzo.yajsw.util.DaemonThreadFactory;

// TODO: Auto-generated Javadoc
/**
* The Class CyclicBufferFileInputStream.
*/
public class CyclicBufferFileInputStream extends BufferedInputStream
{

  /**
   * Instantiates a new cyclic buffer file input stream.
   *
   * @param file
   *            the file
   *
   * @throws FileNotFoundException
   *             the file not found exception
   * @throws IOException
   *             Signals that an I/O exception has occurred.
   */
  public CyclicBufferFileInputStream(File file) throws FileNotFoundException, IOException
  {
    super(newInputStream(file));
  }

  /**
   * New input stream.
   *
   * @param file
   *            the file
   *
   * @return the input stream
   *
   * @throws IOException
   *             Signals that an I/O exception has occurred.
   */
  public static InputStream newInputStream(final File file) throws IOException
  {

    return new InputStream()
    {

      boolean        closed  = false;
      boolean        opened  = false;
      Lock        lock  = new ReentrantLock();
      RandomAccessFile  raf;
      ByteBuffer      buf;
      ByteBuffer      posBuf;
      ByteBuffer      lockBuf;

      synchronized void open()
      {
        if (opened)
          return;
        while (!opened && !closed)
        {
          lock.lock();
          if (file.exists())
            try
            {
              // System.out.println("open "+file);
              if (raf == null)
                raf = new RandomAccessFile(file, "r");
              buf = raf.getChannel().map(FileChannel.MapMode.READ_ONLY, 5, CyclicBufferFilePrintStream.length - 5);
              posBuf = raf.getChannel().map(FileChannel.MapMode.READ_ONLY, 1, 4);
              lockBuf = raf.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, 1);
              opened = true;
            }
            catch (Exception ex)
            {
              System.out.println(ex.getMessage());
            }
          lock.unlock();
          if (!opened)
            try
            {
              Thread.sleep(200);
            }
            catch (InterruptedException e)
            {
              e.printStackTrace();
              Thread.currentThread().interrupt();
            }
        }

      }

      @Override
      public void close()
      {
        // lock.lock();
        closed = true;
        try
        {
          if (raf != null)
            raf.close();
          buf = null;
          System.gc();
          Thread.yield();
        }
        catch (IOException e)
        {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        // lock.unlock();
      }

      @Override
      public int read() throws IOException
      {
        if (!buf.hasRemaining())
        {
          buf.position(0);
        }
        while (getPosition() == buf.position() && !closed)
        {
          try
          {
            Thread.sleep(100);
          }
          catch (InterruptedException e)
          {
            e.printStackTrace();
            return -1;
          }
        }
        if (closed)
        {
          return -1;
        }
        return buf.get();
      }

      private int getPosition()
      {
        posBuf.position(0);
        waitUnlocked();
        return posBuf.getInt();
      }

      private void waitUnlocked()
      {
        return;
        /*
         * lockBuf.position(0); boolean free = lockBuf.get() == 0; while
         * (!free) { try { Thread.sleep(50); } catch
         * (InterruptedException e) { // TODO Auto-generated catch block
         * e.printStackTrace(); return; } lockBuf.position(0); free =
         * lockBuf.get() == 0; }
         */
      }

      @Override
      public int read(byte[] bytes, int off, int len) throws IOException
      {
        // System.out.println("read "+buf.position());
        open();
        lock.lock();
        if (!buf.hasRemaining())
        {
          buf.position(0);
        }
        while (!closed && getPosition() == buf.position())
        {
          try
          {
            lock.unlock();
            Thread.sleep(100);
            lock.lock();
          }
          catch (InterruptedException e)
          {
            e.printStackTrace();
            lock.unlock();
            return -1;
          }
        }
        if (closed)
        {
          lock.unlock();
          return -1;
        }
        int toRead = getPosition() - buf.position();
        if (toRead < 0)
          toRead = buf.remaining();
        if (toRead > len)
          toRead = len;
        buf.get(bytes, off, toRead);
        lock.unlock();
        return toRead;
      }
    };
  }

  /**
   * The main method.
   *
   * @param args
   *            the arguments
   * @throws Exception
   * @throws FileNotFoundException
   */
  public static void main(String[] args)
  {
    CyclicBufferFileInputStream reader = null;
    try
    {
      reader = new CyclicBufferFileInputStream(new File("test.dat"));
    }
    catch (FileNotFoundException e)
    {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
    InputStreamReader isr = new InputStreamReader(reader);
    final BufferedReader br = new BufferedReader(isr);
    Executor executor = Executors.newCachedThreadPool(new DaemonThreadFactory("test"));
    executor.execute(new Runnable()
    {

      public void run()
      {
        String line = null;
        try
        {
          while ((line = br.readLine()) != null)
            System.out.println(line);
          System.out.println(line);
          System.out.flush();
        }
        catch (Exception ex)
        {
          ex.printStackTrace();
        }
      }

    });
    try
    {
      Thread.sleep(100000);
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
      Thread.currentThread().interrupt();
    }
  }

}
TOP

Related Classes of org.rzo.yajsw.io.CyclicBufferFileInputStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.