Tuesday, June 9, 2009

Implementing File Operations for multiple OS

In my work, there was a need for implementing a solution where we could have OS specific operations for Windows and Unix. Certain operations like copying. Moving and creating directory are done far more efficiently when done with OS specific commands.

We were using Spring and what I am now going to show is the solution we implemented.

I had one interface called IFileOperations which had all the file Operations. The implementing class is FileOperations. This is implemented as an initializing bean.
It initializes the current OS and delegated OS specific operations to the current OS class.

There is one more interface called
OSDependentFileOps. There are two implementing classes for it UnixSpecificFileOps and WindowsSpecificFileOps. These two are also beans.













public class FileOperations implements InitializingBean, IFileOperations {

private Logger logger = Logger.getLogger(getClass().getName());

private OSDependentFileOps _windowsOps;

private OSDependentFileOps _unixOps;

private OSDependentFileOps _currentOSOps;

private String fileSeperator;



public void afterPropertiesSet() throws Exception {
String os = System.getProperty("os.name");
os = os.toUpperCase();
logger.log(Level.INFO, "OS = " + os);
fileSeperator = ImageApplicationConstants.SYMBOL_FORWARDSLASH;
_currentOSOps = _unixOps;
if(os.startsWith("WINDOWS")) {
_currentOSOps = _windowsOps;
fileSeperator = ImageApplicationConstants.SYMBOL_FORWARDSLASH;
logger.log(Level.INFO, "WINDOWS LIKE OS");
}
}

public Boolean createDirectoryStructure(String directoryStructureToCreate) {
return _currentOSOps.createDirectoryStructure(directoryStructureToCreate);
}

public Boolean deleteDirectoryStructure(String directoryStructureToDelete) {
return _currentOSOps.deleteDirectoryStructure(directoryStructureToDelete);
}

public Boolean moveFile(String fromPath, String toPath) {
return _currentOSOps.moveFile(fromPath, toPath);
}

public Boolean copyFile(String fromPath, String toPath) {
return _currentOSOps.copyFile(fromPath, toPath);
}

}

public interface OSDependentFileOps {

public abstract Boolean createDirectoryStructure(
String directoryStructureToCreate);

public abstract Boolean deleteDirectoryStructure(String directoryStructureToDelete);

public abstract Boolean createDirectoryStructure(String baseDirectory,
String directoryStructureToCreate);
public abstract Boolean moveFile(String fromPath, String toPath);

public abstract Boolean copyFile(String fromPath, String toPath);

}



public class UnixSpecificFileOps implements OSDependentFileOps {

private Logger logger = Logger.getLogger(getClass().getName());


public Boolean createDirectoryStructure(
String directoryStructureToCreate) {
logger.log(Level.INFO, "" + directoryStructureToCreate);
List command = new ArrayList();
command.add("mkdir");
command.add("-p");
command.add("–m 777");
command.add(directoryStructureToCreate);
logger.log(Level.INFO, "" + command);
return CommandExecutor.exec((String[]) command.toArray(new String[1]));
}
public Boolean deleteDirectoryStructure(
String directoryStructureToDelete) {
logger.log(Level.INFO, "" + directoryStructureToDelete);
List command = new ArrayList();
command.add("rmdir");
command.add(directoryStructureToDelete);
logger.log(Level.INFO, "" + command);
return CommandExecutor.exec((String[]) command.toArray(new String[1]));
}

public Boolean createDirectoryStructure(String baseDirectory,
String directoryStructureToCreate) {
logger.log(Level.INFO, "" + baseDirectory);
logger.log(Level.INFO, "" + directoryStructureToCreate);
List command = new ArrayList();
command.add("cd");
command.add(baseDirectory);
boolean baseDirExists = CommandExecutor.exec((String[]) command.toArray(new String[1]));
if(baseDirExists) {
List command2 = new ArrayList();
command2.add("mkdir");
command2.add(directoryStructureToCreate);
logger.log(Level.INFO, "" + command2);
return CommandExecutor.exec((String[]) command2.toArray(new String[1]));
} else {
logger.log(Level.SEVERE, "Directory Structure not found for " + command);
return false;
}
}

public Boolean moveFile(String fromPath, String toPath) {
List command = new ArrayList();
fromPath = CommonStringUtils.replaceAllString(fromPath, "\\", "/");
toPath = CommonStringUtils.replaceAllString(toPath, "\\", "/");
command.add("mv");
logger.log(Level.INFO, "MOVING from Path = " + fromPath + " toPath = " + toPath);
command.add(fromPath);
command.add(toPath);
logger.log(Level.INFO, "" + command);
Boolean exec = CommandExecutor.exec((String[]) command
.toArray(new String[1]));
return exec;
}

public Boolean copyFile(String fromPath, String toPath) {
List command = new ArrayList();
fromPath = CommonStringUtils.replaceAllString(fromPath, "\\", "/");
toPath = CommonStringUtils.replaceAllString(toPath, "\\", "/");
command.add("cp");
logger.log(Level.INFO, "COPYING from Path = " + fromPath + " toPath = " + toPath);
command.add(fromPath);
command.add(toPath);
logger.log(Level.INFO, "" + command);
Boolean exec = CommandExecutor.exec((String[]) command
.toArray(new String[1]));
return exec;
}


}


public class CommandExecutor {



public static Boolean exec(String[] command) {
Process proc;
StringBuffer cmdStr= new StringBuffer();
for(int i=0; i<command.length;i++){
cmdStr.append(command[i].trim());
if(i!=command.length-1){
cmdStr.append(" ");
}
}
try {
proc = Runtime.getRuntime().exec(cmdStr.toString());
} catch (IOException e) {
return new Boolean(false);
}


int exitStatus;

while (true) {
try {
exitStatus = proc.waitFor();
break;
} catch (java.lang.InterruptedException e) {
}
}
if (exitStatus == 0) {
InputStream is = proc.getInputStream();
readStreamData(is);
}
if (exitStatus != 0) {
InputStream e = proc.getErrorStream();
String error = readStreamData(e);
}
return new Boolean(exitStatus == 0);
}

private static String readStreamData(InputStream e) {
BufferedInputStream bre = new BufferedInputStream(e);
String output = new String(" ");
try {
int readInt = bre.read();
while (readInt != -1) {
char c = (char) readInt;
output = output + c;
readInt = bre.read();
}
} catch (IOException e1) {
e1.printStackTrace();
}
return output;
}
}

No comments:

Post a Comment