// rename() and delete() use this method to ensure that the parent directory // of the source does not vanish. private void createParent(Path path) throws IOException { Path parent = path.getParent(); if (parent != null) { String key = pathToKey(makeAbsolute(parent)); if (key.length() > 0) { store.storeEmptyFile(key + FOLDER_SUFFIX); } } }
private boolean mkdir(Path f) throws IOException { try { FileStatus fileStatus = getFileStatus(f); if (!fileStatus.isDir()) { throw new IOException( String.format("Can't make directory for path '%s' since it is a file.", f)); } } catch (FileNotFoundException e) { LOG.debug("Making dir '" + f + "' in S3"); String key = pathToKey(f) + FOLDER_SUFFIX; store.storeEmptyFile(key); } return true; }
@Override public boolean rename(Path src, Path dst) throws IOException { String srcKey = pathToKey(makeAbsolute(src)); if (srcKey.length() == 0) { // Cannot rename root of file system return false; } final String debugPreamble = "Renaming '" + src + "' to '" + dst + "' - "; // Figure out the final destination String dstKey; try { boolean dstIsFile = getFileStatus(dst).isFile(); if (dstIsFile) { if (LOG.isDebugEnabled()) { LOG.debug(debugPreamble + "returning false as dst is an already existing file"); } return false; } else { if (LOG.isDebugEnabled()) { LOG.debug(debugPreamble + "using dst as output directory"); } dstKey = pathToKey(makeAbsolute(new Path(dst, src.getName()))); } } catch (FileNotFoundException e) { if (LOG.isDebugEnabled()) { LOG.debug(debugPreamble + "using dst as output destination"); } dstKey = pathToKey(makeAbsolute(dst)); try { if (getFileStatus(dst.getParent()).isFile()) { if (LOG.isDebugEnabled()) { LOG.debug(debugPreamble + "returning false as dst parent exists and is a file"); } return false; } } catch (FileNotFoundException ex) { if (LOG.isDebugEnabled()) { LOG.debug(debugPreamble + "returning false as dst parent does not exist"); } return false; } } boolean srcIsFile; try { srcIsFile = getFileStatus(src).isFile(); } catch (FileNotFoundException e) { if (LOG.isDebugEnabled()) { LOG.debug(debugPreamble + "returning false as src does not exist"); } return false; } if (srcIsFile) { if (LOG.isDebugEnabled()) { LOG.debug(debugPreamble + "src is file, so doing copy then delete in S3"); } store.copy(srcKey, dstKey); store.delete(srcKey); } else { if (LOG.isDebugEnabled()) { LOG.debug(debugPreamble + "src is directory, so copying contents"); } store.storeEmptyFile(dstKey + FOLDER_SUFFIX); List<String> keysToDelete = new ArrayList<String>(); String priorLastKey = null; do { PartialListing listing = store.list(srcKey, S3_MAX_LISTING_LENGTH, priorLastKey, true); for (FileMetadata file : listing.getFiles()) { keysToDelete.add(file.getKey()); store.copy(file.getKey(), dstKey + file.getKey().substring(srcKey.length())); } priorLastKey = listing.getPriorLastKey(); } while (priorLastKey != null); if (LOG.isDebugEnabled()) { LOG.debug(debugPreamble + "all files in src copied, now removing src files"); } for (String key : keysToDelete) { store.delete(key); } try { store.delete(srcKey + FOLDER_SUFFIX); } catch (FileNotFoundException e) { // this is fine, we don't require a marker } if (LOG.isDebugEnabled()) { LOG.debug(debugPreamble + "done"); } } return true; }