FileSystem類是與hadoop的檔案系統互動的重要接口。雖然我們隻是着重于HDFS的實作,但我們在編碼時一般也要注意代碼在FileSystem不同子類檔案系統之間的可移植性。這是非常有用的,比如說你可以非常友善的直接用同樣的代碼在你的本地檔案系統上進行測試。
FSDataInputStream:
與URL的openStream()方法傳回InputStream不同,FileSystem的open()方法傳回的是一個FSDataInputStream對象(繼承關系:java.io.InputStream --> java.io.FilterInputStream --> java.io.DataInputStream --> org.apache.hadoop.fs.FSDataInputStream)。由于FSDataInputStream實作了 Closeable , DataInput , PositionedReadable , Seekable 等接口,你可以從流中的任意一個位置讀取資料。
下面我們看一些使用這些API的例子:
//将hdfs中的檔案從控制台列印出來
public class hdfsTest{
public static void main(String[] args) throws IOException, URISyntaxException{
String PATH="hdfs://192.168.12.100:9000/data/test.txt";
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(URI.create(PATH), conf);
InputStream in = null;
try{
in=fs.open(new Path(PATH)); //使用open函數擷取檔案的輸入流
IOUtils.copyBytes(in, System.out, 4096, false);
}finally{
IOUtils.closeStream(in);
}
}
}
//seek可以定位檔案的絕對位置,skip定位到現在位置的相對位置
public static void main(String[] args) throws IOException, URISyntaxException{
String PATH="hdfs://192.168.12.100:9000/data/test.txt";
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(URI.create(PATH), conf);
FSDataInputStream in = null;
try{
in=fs.open(new Path(PATH)); //open傳回FSDataInputStream對象
IOUtils.copyBytes(in, System.out, 4096, false);
in.seek(0);
IOUtils.copyBytes(in, System.out, 4096, false);
}finally{
IOUtils.closeStream(in);
}
}
//create()用來建立一個檔案,此方法有多個重載版本,允許我們指定是否需要強制覆寫已有的檔案,檔案備份數量,寫入檔案時所用的緩沖區大小,檔案塊和檔案權限
public static void main(String[] args) throws IOException, URISyntaxException{
String dst="hdfs://192.168.12.100:9000/data/test.txt";
String src="/root/Desktop/test.txt";
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(URI.create(dst), conf);
InputStream in =new BufferedInputStream(new FileInputStream(src));
OutputStream out=fs.create(new Path(dst),new Progressable(){ //progressable對象顯示了在建立檔案的過程
public void progress() {
System.out.print(".");
}
});
IOUtils.copyBytes(in, out, 4096, true);
}
//FileStatus擷取檔案或者目錄的資訊,這個類封裝了檔案長度,塊大小,備份,修改時間,所有者以及權限資訊
public static void main(String[] args) throws IOException, URISyntaxException{
String dst="hdfs://192.168.12.100:9000/data/test.txt";
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(URI.create(dst), conf);
FileStatus status=fs.getFileStatus(new Path(dst));
System.out.println(status.getPath());
System.out.println(status.getLen());
System.out.println(status.getBlockSize());
System.out.println(status.getOwner());
System.out.println(status.getGroup());
System.out.println(status.getPermission());
System.out.println(status.getReplication());
}
//列出某些目錄的内容
public static void main(String[] args) throws IOException, URISyntaxException{
String dst="hdfs://192.168.12.100:9000/";
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(URI.create(dst), conf);
Path path=new Path(dst);
FileStatus[] status=fs.listStatus(path);
Path[] listedPaths=FileUtil.stat2Paths(status); fileUtil中的stat2paths方法将一個FileStatus對象數組轉換為Path對象數組
for(Path p:listedPaths){
System.out.println(p);
}
}
//mkdirs是建立目錄的方法
public static void main(String[] args) throws IOException, URISyntaxException{
String src="/dirs";
Path path=new Path(src);
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(URI.create("hdfs://192.168.12.100:9000/"),conf);
fs.mkdirs(path);
}
//rename重命名檔案
public static void main(String[] args) throws IOException, URISyntaxException{
String file="hdfs://192.168.12.100:9000/data/test.txt";
String newfile="/data/mytest.txt";
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(URI.create(file),conf);
fs.rename(new Path(file), new Path(newfile));
}
//删除檔案
public static void main(String[] args) throws IOException, URISyntaxException{
String file="hdfs://192.168.12.100:9000/data/";
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(URI.create(file),conf);
fs.delete(new Path("/data/mytest.txt"));
}