org.globus.util.Tail Maven / Gradle / Ivy
/*
* Copyright 1999-2010 University of Chicago
*
* 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.globus.util;
import java.util.List;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Collections;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.File;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Tail implements Runnable {
private static final int CHUNK_SIZE = 2048;
private byte [] buffer;
private boolean _stop = false;
private List list = null;
private Thread _thread;
private Log _logger;
public Tail() {
buffer = new byte[CHUNK_SIZE];
list = Collections.synchronizedList(new LinkedList());
}
public void setLog(Log logger) {
_logger = logger;
}
public void start() {
_thread = new Thread(this);
_thread.start();
}
class FileWatcher {
private RandomAccessFile _ras;
private OutputStream _out;
private long _pos;
public FileWatcher(File file, OutputStream out, int pos)
throws IOException {
_ras = new RandomAccessFile(file, "r");
_out = out;
_pos = pos;
}
public void init()
throws IOException {
_ras.seek(_pos);
}
public long getDiff()
throws IOException {
return _ras.length() - _pos;
}
public void moveBuffer(byte [] buffer, int size)
throws IOException {
_ras.readFully(buffer, 0, size);
_pos += size;
if (_logger.isDebugEnabled()) {
_logger.debug("[tail] output size: " + size);
}
_out.write(buffer, 0, size);
}
public void close() {
try {
_ras.close();
} catch(Exception e) {}
try {
_out.close();
} catch (Exception e) {}
}
}
public void join()
throws InterruptedException {
_thread.join();
}
public void addFile(File file, OutputStream out, int pos)
throws IOException {
list.add(new FileWatcher(file, out, pos));
}
public void run() {
_logger.debug("[tail] running...");
long len;
int size;
Iterator iter = null;
FileWatcher watcher = null;
try {
iter = list.iterator();
while(iter.hasNext()) {
watcher = (FileWatcher)iter.next();
watcher.init();
}
while(!isDone()) {
try {
Thread.sleep(2000);
} catch(Exception e) {
}
iter = list.iterator();
while(iter.hasNext()) {
watcher = (FileWatcher)iter.next();
len = watcher.getDiff();
if (len <= 0) continue;
while(len > 0) {
size = (len > CHUNK_SIZE) ? CHUNK_SIZE : (int)len;
watcher.moveBuffer(buffer, size);
len -= size;
}
}
}
} catch(IOException e) {
_logger.debug("Unexpected error.", e);
} finally {
close();
}
_logger.debug("[tail] done.");
}
private boolean isDone()
throws IOException {
if (!_stop) return false;
Iterator iter = null;
FileWatcher watcher = null;
iter = list.iterator();
while(iter.hasNext()) {
watcher = (FileWatcher)iter.next();
if (watcher.getDiff() > 0) return false;
}
return true;
}
private void close() {
Iterator iter = null;
FileWatcher watcher = null;
iter = list.iterator();
while(iter.hasNext()) {
watcher = (FileWatcher)iter.next();
watcher.close();
}
}
public void stop() {
_logger.debug("[tail] stop called");
_stop = true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy