使用java的大型日志文件的“尾部-10”实现

时间:2013-11-27 04:32:05

标签: java linux

我知道linux可以安装在物理内存较少的机器上。有没有办法用1GB RAM读取4GB日志文件?基本上我想从大日志文件中读取几行。该行可以是大型日志文件中的任何位置。 - 如果有人可以帮助我理解linux尾部实现,我可以在java中尝试相同。 - 至少应该使用哪个java I / O包来按需读取行,而不是在物理内存上加载完整文件然后逐行读取。

1 个答案:

答案 0 :(得分:1)

我认为你可以使用这样的东西...... !!!

/**
* TODO Description go here.

 * @author Rajakrishna V. Reddy
 * @version 1.0
*/

@InterfaceAudience.Public

@InterfaceStability.Evolving

public abstract class FileTailer extends AbstractFileNotificationListener

{

    /** The logger to log the debugging messages as application runs. */
    private final Logger logger;

    /** The tail text. */
    private final StringBuilder tailText = new StringBuilder(256);

    /** The file watcher. */
    private final FileWatcher fileWatcher;

    /**
     * Instantiates a new file tailer.
     * 
     * @param logFileName
     *            the log file name
     * @throws FileNotFoundException
     *             the file not found exception
     */
    public FileTailer(String logFileName) throws FileNotFoundException
    {
            logger = Logger.getLogger(FileTailer.class);
            fileWatcher = FileWatcher.getFileWatcher();
            fileWatcher.registerFileNotificationListener(this, logFileName);
            fileWatcher.start();
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.mt.filewatcher.listener.AbstractFileNotificationListener#onModifyFile
     * (com.mt.filewatcher.info.FileInfo, com.mt.filewatcher.info.FileInfo)
     */
    @Override
    public final synchronized void onModifyFile(FileInfo oldFileInfo, FileInfo newFileInfo)
    {
            tailText.setLength(0);
            final String name = oldFileInfo.getAbsolutePath();
            RandomAccessFile randomFile = null;
            try
            {
                    randomFile = new RandomAccessFile(new File(name), "r");
                    final long offset = getOffset(oldFileInfo, newFileInfo);
                    if (offset > 0)
                    {
                            randomFile.seek(offset-1); // use native seek method to skip bytes
                    }
                    byte[] bytes = new byte[1024];
                    int noOfRead = -1;
                    while ((noOfRead = randomFile.read(bytes)) > 0) // Best approach than reading line by line. 
                    {
                            for (int i = 0; i < noOfRead; i++)
                            {
                                    tailText.append((char)bytes[i]);
                            }
                            bytes = new byte[1024];
                    }

                    final String tailedText = tailText.toString();
                    tail(tailedText);
                    if (tailedText != null && tailedText.contains("\n"))
                    {
                            final String[] lines = tailedText.split("\n");
                            for (String line : lines)
                            {
                                    tailLineByLine(line);
                            }
                    }
                    else
                    {
                            tailLineByLine(tailedText);
                    }
            }
            catch (IOException e)
            {
                    logger.error("Exception in tailing: ", e);
            }
            finally
            {
                    if (randomFile != null)
                    {
                            try
                            {
                                    randomFile.close();
                            }
                            catch (IOException e)
                            {
                                    logger.error("Exception in closing the file: ", e);
                            }
                    }
            }
    }

    /**
     * Gets the tailed text.
     * @see #tailLineByLine(String)
     * 
     * @param tailedText
     *            the tailed text
     */
    public abstract void tail(String tailedText);

    /**
     * Gets the line by line of the tailed text of the file as it is appending
     * into file.
     * <br><b>Note: This line does not contain the new line character.</b>
     * 
     * @param tailedLine
     *            the tailed line
     */
    public void tailLineByLine(String tailedLine)
    {
            //TODO
    }

    /**
     * Gets the offset of the given old FileInfo.
     * 
     * @param oldFileInfo
     *            the old file info
     * @param newFileInfo
     *            the new file info
     * @return the offset
     */
    protected long getOffset(FileInfo oldFileInfo, FileInfo newFileInfo)
    {
            if (newFileInfo.getSize() < oldFileInfo.getSize())
            {
                    return -1;
            }
            return oldFileInfo.getSize();
    }

    /**
     * The main method.
     * 
     * @param args
     *            the args
     * @throws FileNotFoundException
     *             the file not found exception
     */
    public static void main(String[] args) throws FileNotFoundException
    {
            System.setProperty(LoggerConstants.LOG_CLASS_FQ_NAME, ConsoleLogger.class.getName());
             //new FileTailer("/krishna/Project/Hyperic/hq-hq/tools/unit_tests").onModifyFile(new FileInfo("/krishna/Project/Hyperic/hq-hq/tools/unit_tests/Raja/hi.txt"),  null);
    }

}