package org.archive.hadoop.io; import java.text.SimpleDateFormat; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.util.Tool; import org.apache.hadoop.util.ToolRunner; public class HDFSTouch implements Tool { protected Configuration conf; public final static String TOOL_NAME = "hdfs-touch"; public final static String TMP_FILENAME = ".tmp_touch_latest"; public final static String FORMAT_STR = "yyyy-MM-dd HH:mm:ss"; public final static String HTTP_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz"; protected SimpleDateFormat formats[] = { new SimpleDateFormat(FORMAT_STR), new SimpleDateFormat(HTTP_FORMAT) }; public static void main(String[] args) throws Exception { int res = ToolRunner.run(new Configuration(), new HDFSTouch(), args); System.exit(res); } public void setConf(Configuration conf) { this.conf = conf; } public Configuration getConf() { return conf; } public static void print_usage() { System.err.println("Usage: " + TOOL_NAME + " [ -d ] HDFS_URL [ TIMESTAMP ]"); System.err.println("Updates the mtime and atime of HDFS_URL to current time, or optional TIMESTAMP"); System.err.println("Accepts following TIMESTAMP formats:"); System.err.println(" " + FORMAT_STR); System.err.println(" " + HTTP_FORMAT); } protected long parseFormats(String arg) { long mtime = -1; for (SimpleDateFormat format : formats) { try { mtime = format.parse(arg).getTime(); return mtime; } catch (Exception exc) { } } if (mtime == -1) { System.err.println("Error parsing timestamp: " + arg + "\nExpected format: " + FORMAT_STR + " or " + HTTP_FORMAT); mtime = System.currentTimeMillis(); } return mtime; } public int run(String[] args) throws Exception { if (args.length < 1) { print_usage(); return 1; } String filePath = null; boolean updateDir = false; if (args.length == 1) { filePath = args[0]; } else { updateDir = (args[0].equals("-d")); filePath = args[1]; } Path path = new Path(filePath); FileSystem fs = path.getFileSystem(conf); if (fs.getFileStatus(path).isDir()) { System.err.println("Can't touch directories in this version\n" + "This is a directory: " + path); return 1; } long mtime = System.currentTimeMillis(); if (args.length >= 3) { mtime = parseFormats(args[2]); } long atime = mtime; fs.setTimes(path, mtime, atime); if (updateDir) { Path tempFilePath = new Path(path.getParent(), TMP_FILENAME); // Create empty output stream FSDataOutputStream out = fs.create(tempFilePath); out.close(); // Delete tmp file fs.delete(tempFilePath, false); } return 0; } }