package com.zhen.hdfs; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.util.Progressable; /** * @author FengZhen * @date 2018年8月12日 * */ public class FileSystemWriteAPI { public static void main(String[] args) { //create(); mkdir(); } /** * FileSystem类有一系列新建文件的方法。 * 1.最简单的方法是给准备建的文件指定一个Path对象,然后返回一个用于写入数据的输出流 * public FSDataOutputStream create(Path f) throws IOException { return create(f, true); } 此方法有多个重载版本,允许我们指定是否需要强制覆盖现有的文件、文件备份数量、写入文件时所用的缓冲区大小、文件块大小以及文件权限。 create方法能够为需要写入且当前不存在的文件创建父目录。尽管这样很方便,但有时不希望这样。如果希望父目录不存在就导致文件写入失败,则应该先调用exists方法检查父目录是否存在 还有一个重载方法Progressable用于传递回调接口,如此一来,可以把数据写入datanode的进度通知给应用。 public interface Progressable { public void progress(); } 2.另一种新建文件的方法是使用append方法在一个已有文件末尾追加数据 public FSDataOutputStream append(Path f) throws IOException { return append(f, getConf().getInt("io.file.buffer.size", 4096), null); } 这样的追加操作允许一个writer打开文件后在访问该文件的最后偏移量处追加数据。有了这个API,某些应用可以创建无边界文件,例如,应用可以在关闭日志文件之后继续追加日志。 该追加操作是可选的,并非所有Hadoop文件系统都实现了该操作。例如,HDFS支持追加,但S3文件系统不支持 */ /** * FSDataOutPutStream对象 * FileSystem实例的create方法返回FSDataOutPutStream对象,与FSDataInPutStream类相似,它也有一个查询文件当前位置的方法 * public long getPos() throws IOException { return position; // return cached position } 但与FSDataInPutStream不同的是,FSDataOutPutStream类不允许在文件中定位。 这是因为HDFS只允许对一个已打开的文件顺序写入,或在现有文件的末尾追加数据。换句话说,它不支持在除文件末尾之外的其它位置进行写入。 */ public static void create() { String localSrc = "/Users/FengZhen/Desktop/hadoop-file/core-site.xml"; String dst = "hdfs://fz/user/hdfs/MapReduce/data/test_create.xml"; Configuration conf = new Configuration(); try { InputStream inputStream = new BufferedInputStream(new FileInputStream(localSrc)); FileSystem fileSystem = FileSystem.get(URI.create(dst), conf); OutputStream outputStream = fileSystem.create(new Path(dst), new Progressable() { public void progress() { System.out.print("."); } }); IOUtils.copyBytes(inputStream, outputStream, 4096, true); } catch (IOException e) { e.printStackTrace(); } } /** * 目录 * FileSystem实例提供了创建目录的方法 * public boolean mkdirs(Path f) throws IOException { return mkdirs(f, FsPermission.getDirDefault()); } 通常,不需要显式创建一个目录,因为调用create方法写入文件时会自动创建父目录 */ public static void mkdir() { String uri = "hdfs://fz/user/hdfs/MapReduce/data/2017/08/11"; Configuration conf = new Configuration(); try { FileSystem fileSystem = FileSystem.get(new URI(uri), conf); fileSystem.mkdirs(new Path(uri)); } catch (IOException e) { e.printStackTrace(); } catch (URISyntaxException e) { e.printStackTrace(); } } }