📄 directorymanager.java
字号:
private void updateExistingFiles(Map existingFiles, Map newFiles) { Iterator iter = existingFiles.entrySet().iterator(); Set toRemove = new HashSet(); // scan all exising files: if some not found in new delete, otherwise // update. At the end newFiles will only contain really new files while (iter.hasNext()) { Map.Entry existingEntry = (Map.Entry)iter.next(); Object key = existingEntry.getKey(); File newFile = (File)newFiles.get(key); if (newFile == null) { // the file has been deleted: remove it from the list if (toRemove == null) toRemove = new HashSet(); toRemove.add(key); } else { // if still exists, then update FileInfo existingInfo = (FileInfo)existingEntry.getValue(); existingInfo.update(newFile, log); newFiles.remove(key); } } // remove if (toRemove != null && toRemove.size() > 0) { String[] keys = (String[])toRemove.toArray(new String[toRemove.size()]); for (int i=0; i < keys.length; i++) { log.warning(ME+": the file '" + keys[i] + "' has apparently been removed from the outside: will not send it. No further action required"); existingFiles.remove(keys[i]); } } // now we only have new files to process iter = newFiles.values().iterator(); while (iter.hasNext()) { File file = (File)iter.next(); FileInfo info = new FileInfo(file, log); existingFiles.put(info.getName(), info); } } /** * Gets all entries which are ready to be sent (i.e. to be published) * * @return all entries as a TreeSet. Elements in the set are of type * FileInfo * * @throws XmlBlasterException if the application has no read or write * rights on the directory */ Set getEntries() throws XmlBlasterException { if (log.isLoggable(Level.FINER)) log.finer(ME+": getEntries"); Map newFiles = getNewFiles(this.directory); updateExistingFiles(this.directoryEntries, newFiles); return prepareEntries(this.directory, this.directoryEntries); } /** * Removes the specified entry from the map. This method does also remove * the entry from the file system or it moves it to the requested directory. * If for some reason this is not * possible, then an exception is thrown. * * @param entryName the name of the entry to remove. * @return false if the entry was not found * @throws XmlBlasterException */ void deleteOrMoveEntry(final String entryName, boolean success) throws XmlBlasterException { try { if (log.isLoggable(Level.FINER)) log.finer(ME+": removeEntry '" + entryName + "'"); File file = new File(entryName); if (!file.exists()) { log.warning(ME+": removeEntry: '" + entryName + "' does not exist on the file system: I will only remove it from my list"); this.directoryEntries.remove(entryName); return; } if (file.isDirectory()) throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_FILEIO, ME + ".removeEntry", "'" + entryName + "' is a directory"); if (!file.canWrite()) throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_FILEIO, ME + ".removeEntry", "no rights to write to '" + entryName + "'"); if (success && this.sentDirectory == null || !success && this.discardedDirectory == null) { if (deleteFile(file)) { this.directoryEntries.remove(entryName); return; } else { throw new XmlBlasterException(this.global, ErrorCode.INTERNAL_UNKNOWN, ME + ".removeEntry", "could not remove entry '" + file.getName() + "': retrying"); } } if (success) { // then do a move moveTo(file, entryName, this.sentDirectory); this.directoryEntries.remove(entryName); } else { moveTo(file, entryName, this.discardedDirectory); this.directoryEntries.remove(entryName); } } catch (XmlBlasterException ex) { throw ex; } catch (Throwable ex) { throw new XmlBlasterException(this.global, ErrorCode.INTERNAL_UNKNOWN, ME + ".removeEntry", "", ex); } } private void moveTo(File file, String origName, File destinationDirectory) throws XmlBlasterException { if (!destinationDirectory.exists()) throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_FILEIO, ME + ".removeEntry", "'" + destinationDirectory.getName() + "' does not exist"); if (!destinationDirectory.isDirectory()) throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_FILEIO, ME + ".removeEntry", "'" + destinationDirectory.getName() + "' is not a directory"); if (!destinationDirectory.canRead()) throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_FILEIO, ME + ".removeEntry", "no rights to read to '" + destinationDirectory.getName() + "'"); if (!destinationDirectory.canWrite()) throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_FILEIO, ME + ".removeEntry", "no rights to write to '" + destinationDirectory.getName() + "'"); if (log.isLoggable(Level.FINE)) log.fine(ME+": File " + file.getAbsolutePath() + " moving to " + destinationDirectory.getAbsolutePath() + ", copyOnMove=" + copyOnMove); String relativeName = FileInfo.getRelativeName(file.getName()); try { File destinationFile = new File(destinationDirectory, relativeName); if (destinationFile.exists()) { boolean ret = deleteFile(destinationFile); if (!ret) throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_FILEIO, ME + ".moveTo", "could not delete the existing file '" + destinationFile.getCanonicalPath() + "' to '" + destinationDirectory.getName() + "' before moving avay '" + relativeName + "' after processing"); } if (copyOnMove) { InputStream inputStream = file.toURL().openStream(); BufferedInputStream bis = new BufferedInputStream(inputStream); try { FileOutputStream os = new FileOutputStream(destinationFile); try { long length = file.length(); long remaining = length; final int BYTE_LENGTH = 100000; // For the moment it is hardcoded byte[] buf = new byte[BYTE_LENGTH]; while (remaining > 0) { int tot = bis.read(buf); remaining -= tot; os.write(buf, 0, tot); } } finally { try { os.close(); } catch (Throwable e) {} } } finally { try { bis.close(); } catch (Throwable e) {} try { inputStream.close(); } catch (Throwable e) {} } String name = file.getAbsolutePath(); boolean deleted = deleteFile(file); if (deleted) { if (log.isLoggable(Level.FINE)) log.fine(ME+": File " + name + " is successfully deleted, copyOnMove=" + copyOnMove); } else { log.warning(ME+": File " + name + " delete call failed: deleted=" + deleted + ", copyOnMove=" + copyOnMove + " exists=" + file.exists()); } } else { boolean ret = file.renameTo(destinationFile); if (!ret) { File orig = new File(origName); if (orig.exists()) { throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_FILEIO, ME + ".moveTo", "Could not move the file '" + relativeName + "' to '" + destinationDirectory.getName() + "' reason: could it be that the destination is not a local file system ? try the flag 'copyOnMove='true' (see http://www.xmlblaster.org/xmlBlaster/doc/requirements/contrib.filewatcher.html"); } else { File dest = new File(destinationDirectory, relativeName); if (!dest.exists()) { log.warning(ME+": Removed published file '" + origName + "' but couldn't create backup '" + destinationDirectory.getName() + "' (see http://www.xmlblaster.org/xmlBlaster/doc/requirements/contrib.filewatcher.html"); } else { log.warning(ME+": Published file '" + origName + "' is already moved to backup '" + destinationDirectory.getName() + "' but java tells us it couldn't be moved, this is strange."); } } } } } catch (XmlBlasterException e) { throw e; } catch (Throwable ex) { log.warning(ME + ": Could not move the file '" + relativeName + "' to '" + destinationDirectory.getName() + "' reason: " + ex.toString()); throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_FILEIO, ME + ".moveTo", "could not move the file '" + relativeName + "' to '" + destinationDirectory.getName() + "' reason: ", ex); } } public FileInputStream getContentStream(FileInfo info) throws XmlBlasterException { String entryName = info.getName(); if (log.isLoggable(Level.FINER)) log.finer(ME+": getContent '" + entryName + "'"); File file = new File(entryName); if (!file.exists()) { log.warning(ME+": getContentAsStream: '" + entryName + "' does not exist on the file system: not sending anything"); this.directoryEntries.remove(entryName); return null; } if (file.isDirectory()) throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_FILEIO, ME + ".getContentAsStream", "'" + entryName + "' is a directory"); if (!file.canWrite()) throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_FILEIO, ME + ".getContentAsStream", "no rights to write from '" + entryName + "'"); try { FileInputStream fis = new FileInputStream(entryName); return fis; } catch (IOException ex) { throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_FILEIO, ME + ".getContent", "", ex); } catch (Throwable ex) { throw new XmlBlasterException(this.global, ErrorCode.INTERNAL_UNKNOWN, ME + ".removeEntry", "", ex); } } /** * Gets the content from the specified file as a byte[]. If this is * not possible it will throw an exception. * * @param info * @return * @throws XmlBlasterException */ public byte[] getContent(FileInfo info) throws XmlBlasterException { try { FileInputStream fis = getContentStream(info); BufferedInputStream bis = new BufferedInputStream(fis); int toRead = (int)info.getSize(); int offset = 0; int tot = 0; byte[] ret = new byte[toRead]; while (tot < toRead) { int available = bis.available(); if (available > 0) { int read = bis.read(ret, offset, available); tot += read; } else { try { Thread.sleep(5L); } catch (Exception e) {} } } return ret; } catch (IOException ex) { throw new XmlBlasterException(this.global, ErrorCode.RESOURCE_FILEIO, ME + ".getContent", "", ex); } catch (Throwable ex) { throw new XmlBlasterException(this.global, ErrorCode.INTERNAL_UNKNOWN, ME + ".removeEntry", "", ex); } } /** java org.xmlBlaster.contrib.filewatcher.DirectoryManager -path /tmp/filewatcher -filter "*.xml" -filterType simple */ public static void main(String[] args) { try { Global global = new Global(args); String path = global.get("path", ".", null, null); File directory = new File(path); String filter = global.get("filter", "*.txt", null, null); String filterType = global.get("filterType", "simple", null, null); boolean trueRegex = false; if ("regex".equalsIgnoreCase(filterType)) trueRegex = true; System.out.println("-----------Configuration:-------------------------"); System.out.println("Directory to look into: '" + directory.getAbsolutePath() + "'"); System.out.println("The " + filterType + " filter is '" + filter + "'"); System.out.println(""); System.out.println("-----------Matching Results:----------------------"); FilenameFilter fileFilter = new FilenameFilter(filter, trueRegex); File[] files = directory.listFiles(fileFilter); if (files == null || files.length < 1) { System.out.println(""); System.out.println("WARN: no files found matching the " + filterType + " expression '" + filter + "'"); System.out.println(""); System.exit(0); } for (int i=0; i < files.length; i++) { System.out.println("file[" + i + "] = " + files[i].getName()); } if (files.length > 0) { System.out.println(""); System.out.println("no more files found"); } } catch (Exception ex) { ex.printStackTrace(); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -