All pastes #947433 Raw Edit

Unbenannt

public text v1 · immutable
·published 2008-03-18 14:25 UTC
rendered paste body
package org.ba.karlsruhe.filehandler;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
import java.util.ArrayList;

/**
 * A wrapper class which deals with reading and writing of files
 *
 */
public class FileHandler {
	private File m_file;
	private boolean m_writeThrough = true;
	private boolean m_hasRead = false;
	
	private ArrayList<String> m_cache = new ArrayList<String>();
	
	/**
	 * Constructs a new file handler.
	 * If the given file does not exist, the handler tries to create it.
	 * 
	 * @param file the file name
	 */
	FileHandler(File file) throws FileHandlerException {
		try {
			// create the file if it does not exist
			if(!file.exists())
				file.createNewFile();
			
			// check if the file permissions are properly set
			if(!file.canRead() || !file.canWrite())
				throw new FileHandlerException("File does not have right read or write permissions.");
		} catch(IOException e) {
			throw new FileHandlerException(e);
		}
		
		m_file = file;
	}
	
	/**
	 * Constructs a new file handler.
	 * If the given file name does not exist, the handler tries to create it.
	 *  
	 * @param fileName the file name
	 */
	FileHandler(String fileName) throws FileHandlerException {
		this(new File(fileName));
	}
	
	/**
	 * If the handler operates in write-through mode, every change to a file
	 * is immediately written to the file (write-through is default)
	 * 
	 * If the handler is in write-behind mode (=not write-through), you must
	 * call write() manually to synchronize the changes
	 * 
	 * @param writeThrough true, if write-through should be enabled
	 */
	public void setWriteThrough(boolean writeThrough) {
		m_writeThrough = writeThrough;
	}
	
	public boolean writeThrough() {
		return m_writeThrough;
	}
	
	/**
	 * Call this method to update the file handler cache.
	 * 
	 * Since we cannot use a notifier like INotify we cannot know when our
	 * file is dirty. So you need to call this method every time you want an
	 * updated cache.
	 * 
	 * @throws FileHandlerException
	 */
	public void read() throws FileHandlerException {
		try {
			BufferedReader reader = new BufferedReader(new FileReader(m_file));
			
			// clear cache
			m_cache.clear();
			
			// read from file line by line
			String currentLine = new String();
			while((currentLine = reader.readLine()) != null)
				m_cache.add(currentLine);
			
			reader.close();
			
			// mark the file to be read at least once
			m_hasRead = true;
		} catch(FileNotFoundException e) {
			throw new FileHandlerException("Could not find file when trying to read. This should never happen.");
		} catch(IOException e) {
			throw new FileHandlerException(e.getCause());
		}
	}
	
	/**
	 * Returns the file's content as an array of strings.
	 * 
	 * @return the file content
	 * @throws FileHandlerException
	 */
	public String[] getContent() throws FileHandlerException {
		// if the file has not been read explicitly, try to read it
		if(!m_hasRead)
			read();
		
		return m_cache.toArray(new String[0]);
	}
	
	/**
	 * Returns the number of lines the file has
	 * 
	 * @return the number of lines
	 * @throws FileHandlerException
	 */
	public int getLineCount() throws FileHandlerException {
		// if the file has not been read explicitly, try to read it
		if(!m_hasRead)
			read();
		
		return m_cache.size();
	}
	
	/**
	 * Returns the file content at the given line or an empty string if the line
	 * number is invalid.
	 * The first line has line number 0.
	 * 
	 * @param lineNumber the line number
	 * @return the line at given line number
	 * @throws FileHandlerException
	 */
	public String getContentAtLine(int lineNumber) throws FileHandlerException {
		// if the file has not been read explicitly, try to read it
		if(!m_hasRead)
			read();
		
		if(validLineNumber(lineNumber))
			return m_cache.get(lineNumber);
		else
			return "";
	}
	
	/**
	 * Sets the line content to a given string at a given line number
	 * 
	 * @param lineNumber the line number
	 * @param line the content
	 * @throws FileHandlerException
	 */
	public void setLine(int lineNumber, String line) throws FileHandlerException {
		if(validLineNumber(lineNumber)) {
			m_cache.set(lineNumber, line);
			tryToWrite();
		}
	}
	
	/**
	 * Appends a line to the file
	 * 
	 * @param line the content
	 * @throws FileHandlerException
	 */
	public void appendLine(String line) throws FileHandlerException {
		m_cache.add(line);
		tryToWrite();
	}
	
	/**
	 * Removes the given line from the file
	 * 
	 * @param lineNumber
	 * @throws FileHandlerException
	 */
	public void removeLine(int lineNumber) throws FileHandlerException {
		if(validLineNumber(lineNumber))
			m_cache.remove(lineNumber);
		tryToWrite();
	}
	
	/**
	 * Removes all lines from the file
	 * @throws FileHandlerException
	 */
	public void removeAllLines() throws FileHandlerException {
		m_cache.clear();
		tryToWrite();
	}
	
	/**
	 * Removes all the lines which contain the given pattern
	 * 
	 * @param match the matching string
	 * @param caseSensitive if true, the match will be treated case-sensitive
	 * @return the amount of strings removed
	 * @throws FileHandlerException
	 */
	public int removeLines(String match, boolean caseSensitive) throws FileHandlerException {
		if(!caseSensitive)
			match = match.toLowerCase();
		
		int matchCount = 0;
		for(int i=0;i<m_cache.size();i++) {
			String compareString;
			if(!caseSensitive)
				compareString = match.toLowerCase();
			else
				compareString = match;
			
			if(m_cache.get(i).contains(compareString)) {
				matchCount++;
				m_cache.remove(i);
			}
		}
		
		tryToWrite();
		
		return matchCount;
	}
	
	public void write() throws FileHandlerException {
		try {
			BufferedWriter writer = new BufferedWriter(new FileWriter(m_file,false));
			
			for(int i=0;i<m_cache.size();i++) {
				writer.write(m_cache.get(i));
				if(i!=m_cache.size()-1)
					writer.newLine();
			}
				
			writer.close();
		} catch(FileNotFoundException e) {
			throw new FileHandlerException("Could not find file when trying to read. This should never happen.");
		} catch(IOException e) {
			throw new FileHandlerException(e.getCause());
		}
	}
	
	private void tryToWrite() throws FileHandlerException {
		if(m_writeThrough)
			write();
	}
	
	private boolean validLineNumber(int lineNumber) {
		return lineNumber >= 0 && lineNumber < m_cache.size();
	}
}