package org.fireflow.service.file.reader; import java.io.File; import java.io.FileInputStream; import java.io.FilenameFilter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.StringTokenizer; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.fireflow.engine.exception.ServiceInvocationException; import org.fireflow.engine.invocation.Message; import org.fireflow.engine.invocation.impl.MessageImpl; import org.fireflow.service.file.FileObject; import org.fireflow.service.file.FileObjectImpl; public class FileReaderImpl implements FileReader{ private static final Log log = LogFactory.getLog(FileReaderImpl.class); FileReadServiceDef service = null; public void setFileReadService(FileReadServiceDef svc){ this.service = svc; } public FileReadServiceDef getFileReadService(){ return service; } public Message<List<FileObject>> readFile(Long startTime)throws ServiceInvocationException{ //首先进行配置校验 if (service==null){ throw new ServiceInvocationException("FileReadService configuration object is null."); } if (StringUtils.isEmpty(service.getDirectory())){ throw new ServiceInvocationException("FileReadService[id="+service.getId()+";name="+service.getName()+"] is invalid: the directory can NOT be empty."); } if (FileReadServiceDef.REMOVE_AFTER_READING.equals(service.getStrategyAfterReading()) && StringUtils.isEmpty(service.getBakupDirectory())){ throw new ServiceInvocationException("FileReadService[id="+service.getId()+";name="+service.getName()+"] is invalid: the bakup directory can NOT be empty when the value of StrategyAfterReading is REMOVE_AFTER_READING"); } File directory = new File(service.getDirectory()); if (!directory.exists() || !directory.isDirectory()){ throw new ServiceInvocationException("FileReadService[id="+service.getId()+";name="+service.getName()+"] is invalid: the directory '"+service.getDirectory()+"' is empty or it is not a directory. "); } File bakupDirectory = null; if (FileReadServiceDef.REMOVE_AFTER_READING.equals(service.getStrategyAfterReading())){ bakupDirectory = new File(service.getBakupDirectory()); if (!bakupDirectory.exists() || !bakupDirectory.isDirectory()){ throw new ServiceInvocationException("FileReadService[id="+service.getId()+";name="+service.getName()+"] is invalid: the bakup directory '"+service.getBakupDirectory()+"' is empty or it is not a directory. "); } } //读取文件 File[] fileList = directory.listFiles(new FilenameFilter(){ public boolean accept(File dir, String name) { String suffixList = service.getFileNameSuffix(); if (StringUtils.isEmpty(suffixList)){ return true; } StringTokenizer tokenizer = new StringTokenizer(suffixList,","); while(tokenizer.hasMoreTokens()){ String suffix = tokenizer.nextToken(); if (name.endsWith(suffix)){ return true; } } return false; } }); MessageImpl<List<FileObject>> result = new MessageImpl<List<FileObject>>(); List<FileObject> readFileList = new ArrayList<FileObject>(); result.setPayload(readFileList); if (fileList==null || fileList.length==0)return result; //先把fileList按照lastModified顺序排序 List<File> fileList2 = new ArrayList<File>(); Collections.addAll(fileList2, fileList); Collections.sort(fileList2, new Comparator<File>(){ public int compare(File o1, File o2) { if (o1.lastModified()<o2.lastModified()){ return -1; }else if (o1.lastModified()>o2.lastModified()){ return 1; }else{ return 0; } } }); int batchSize = service.getBatchSize()<=0?1:service.getBatchSize(); for (File f : fileList){ if (startTime==null || startTime<=0 || (startTime>0 && f.lastModified()>startTime)){ FileObjectImpl fObj = new FileObjectImpl(); fObj.setFileName(f.getName()); fObj.setLastestEditTime(f.lastModified()); fObj.setContent(readFile(f)); fObj.setAbsolutePath(f.getAbsolutePath()); fObj.setCharset(service.getCharset()); fObj.setFileType(service.getFileType()); readFileList.add(fObj); //将文件改名或者转移 if (FileReadServiceDef.RENAME_AFTER_READING.equals(service.getStrategyAfterReading())){ File newFile = new File(f.getAbsolutePath()+FileReadServiceDef.READ_FILE_SUFFIX); if (newFile.exists()){ newFile.delete(); } boolean b = f.renameTo(newFile); }else if (FileReadServiceDef.REMOVE_AFTER_READING.equals(service.getStrategyAfterReading())){ File newFile = new File(bakupDirectory.getAbsolutePath()+File.separator+f.getName()); if (newFile.exists()){ newFile.delete(); } boolean b = f.renameTo(newFile); } } if (readFileList.size()>=batchSize){ break; } } if (readFileList.size()>0){ Long lastModified = readFileList.get(readFileList.size()-1).getLastModified(); result.getHeaders().put("NEXT_START_TIME", lastModified.toString()); } return result; } private byte[] readFile(File f){ try{ int byteread = 0; int totalRead = 0; FileInputStream fIn = new FileInputStream(f); byte[] content = new byte[fIn.available()]; int offset = 0; int numRead = 0; while (offset < content.length && (numRead=fIn.read(content, offset, content.length-offset)) >= 0) { offset += numRead; } // Ensure all the bytes have been read in if (offset < content.length) { throw new IOException("Could not completely read file "+f.getName()); } fIn.close(); return content; }catch(IOException e){ log.error(e); return null; } } }