/* * ALMA - Atacama Large Millimiter Array (c) European Southern Observatory, 2010 * * 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. * * 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. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package alma.acs.logtools.monitor.file; import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; import alma.acs.util.IsoDateFormat; /** * Help managing the text file to write stats into. * <P> * The helper generates a new file when the size * of the current size is greater then a threshold. * <P> * The name of each file is composed of the extension * plus the time stamp of the creation. * <P> * <B>Note</B>: in case of error creating a file, the object will * discard all next writing requests. * * @author acaproni * @since ACS 8.1.0 */ public class FileHelper { /** * To improve performance the checking of the length of the * files is done after <code>CHECK_INTERVAL</code> writings. */ private static final int CHECK_INTERVAL=6; /** * The property remember how many writings have been * done since the last time the length of the file * was checked. */ private int currentWritingOps=0; /** * The max dimension of each file of log in bytes. */ private final long MAX_LOG_FILE_SIZE=1024*1024*1024; // 1 Gb /** * The folder to create file into */ public final String folder; /** * The folder to create file into */ public final String extension; /** * The header to write on top of each new file * (can be <code>null</code> and empty) */ private final String header; /** * The writer for output */ private PrintStream outStream=null; /** * The file for output */ private File outputFile=null; /** * If <code>true</code> the object has been closed */ private volatile boolean closed=false; /** * Constructor * @param folder The folder * @param ext The extension * @param header The header to write on top of each new file * (can be <code>null</code> and empty) */ public FileHelper(String folder, String ext, String header) { if (folder==null || folder.isEmpty()) { throw new IllegalArgumentException("Invalid folder"); } if (ext==null || ext.isEmpty()) { throw new IllegalArgumentException("Invalid extension"); } // Check if the folder is valid File f = new File(folder); if (!f.isDirectory() || !f.canWrite()) { throw new IllegalArgumentException("Invalid folder: "+folder); } this.folder=folder; this.extension=ext; this.header=header; getNewFile(); } /** * Check if the file is valid and eventually creates * a new one */ private void checkFile() { if (outputFile==null || outputFile.length()>MAX_LOG_FILE_SIZE) { getNewFile(); } } /** * Check the length of the file and eventually creates * a new one. * */ private void getNewFile() { closeFile(); String now=IsoDateFormat.formatCurrentDate(); String fileName=extension+"_"+now+".dat"; outputFile= new File(fileName); FileOutputStream fos; outStream=null; try { fos= new FileOutputStream(outputFile); } catch (Throwable t) { outputFile=null; closed=true; return; } outStream=new PrintStream(fos); if (header!=null && !header.isEmpty()) { outStream.print(header); } } /** * Close the current file */ private void closeFile() { if (outputFile!=null) { try { outStream.flush(); outStream.close(); } catch (Throwable t) { // Nothing to do... log a message System.err.println("Error closing file: "+t.getMessage()); t.printStackTrace(System.err); } finally { outStream=null; outputFile=null; } } } /** * Write the string in the file. * * @param s The string to append to the file */ public synchronized void put(String s) { if (s==null || s.isEmpty() || closed) { return; } outStream.print(s); if (++currentWritingOps>=CHECK_INTERVAL) { checkFile(); currentWritingOps=0; } } /** * Close the object in order to reject any further * writing request and release the file. */ public synchronized void close() { closed=true; closeFile(); } }