参考:https://www.cnblogs.com/dj-blog/p/9178465.html
注意:
1>上传文件的前提:必须在hdfs中先创建一个文件 create
2>下载文件的前提:必须在hdfs中先打开这个文件 open
3> user的含义:HADOOP_USER_NAME
4>conf的作用:
5>fileSystem的层次结构:
①创建文件夹:mkdirs默认就会递归的创建出多级目录
public class App1
{
public static void main(String[] args) throws Exception
{
Configuration conf = new Configuration();
FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop20:9000/"), conf, "root");
//创建文件夹的方式:可以迭代创建
fileSystem.mkdirs(new Path("hdfs://hadoop20:9000/dir1/dir2"));
}
}
②从本地文件系统(本地参考的是eclipse安装在linux上还是windows上)上传文件到HDFS上(注意:目标文件的名字可以和源文件的名字不同,内容同样会拷贝)
public class App1
{
public static void main(String[] args) throws Exception
{
Configuration conf = new Configuration();
FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop20:9000/"), conf, "root");
//从本地上传文件到HDFS
FSDataOutputStream fw = fileSystem.create(new Path("/dir1/dir2/file.txt"));
FileInputStream fr = new FileInputStream("C:\\file.txt");
IOUtils.copyBytes(fr,fw,1024,true);
}
}
上面的代码也可以用下面简单的代码来替代:
public class App1
{
public static void main(String[] args) throws Exception
{
Configuration conf = new Configuration();
FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop20:9000/"), conf, "root");
//从本地上传文件到HDFS
fileSystem.copyFromLocalFile(new Path("C:\\file.txt"), new Path("hdfs://hadoop20:9000/dir1/dir2/file.txt"));
}
}
③从HDFS中下载文件到本地(本地参考的是eclipse安装在linux上还是windows上)
public class App1
{
public static void main(String[] args) throws Exception
{
Configuration conf = new Configuration();
FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop20:9000/"), conf, "root");
//从hdfs中下载文件到本地
FSDataInputStream fr = fileSystem.open(new Path("hdfs://hadoop20:9000/dir1/dir2/file.txt"));
IOUtils.copyBytes(fr,System.out, 1024, true);
}
}
public class App1
{
public static void main(String[] args) throws Exception
{
Configuration conf = new Configuration();
FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop20:9000/"), conf, "root");
//从hdfs中下载文件到本地
fileSystem.copyToLocalFile(new Path("hdfs://hadoop20:9000/dir1/dir2/file.txt"), new Path("D:\\file.txt"));
}
}
fileSystem.copyToLocalFile(new Path("hdfs://hadoop20:9000/dir1/dir2/file.txt"), new Path("D:\\file.txt"));
改为:
fileSystem.copyToLocalFile(false,new Path("hdfs://hadoop20:9000/dir1/dir2/file.txt"), new Path("D:\\file.txt"),true);
错误原因:
在使用copyToLocalFile(Path src, Path dst)方法时可能导致 setPermission文件本地文件效验失败,因此使用copyToLocalFile( boolean delSrc,Path src, Path dst, boolean useRawLocalFileSystem),其中:
boolean delSrc 指是否将原文件删除
Path src 指要下载的文件路径
Path dst 指将文件下载到的路径
boolean useRawLocalFileSystem 是否开启文件效验
④删除文件或者文件夹(会递归到下层,不会到上层)
public boolean delete(Path f, boolean recursive) throws IOException
如果f是一个文件或空目录,那么recursive的值就会被忽略:
/user/mart_cfo/word.txt
/user/mart_risk
如果f不是一个空目录:只有在recrusive值为true时,非空目录及其子内容才会被删除(否则会抛出IOException异常)。
/user/mart_risk/jdk1.7.0_25x64.zip
public class App1
{
public static void main(String[] args) throws Exception
{
Configuration conf = new Configuration();
FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop20:9000/"), conf, "root");
//删除文件或文件夹:第二个参数代表是否递归删除,类似于Python的那个
fileSystem.delete(new Path("hdfs://hadoop20:9000/dir1/dir2/file.txt"), false);
}
}
import java.io.FileInputStream;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.junit.Test;
public class hdfs_utils_1
{
public static void main(String[] args) throws Exception
{
Configuration config = new Configuration();
FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop11:9000"), config,"root");
//mv操作:竟然叫做rename
fileSystem.rename(new Path("/word.txt") ,new Path("/user/mart_cfo/"));
}
}
(6)获取文件或者文件夹的元数据信息
第一:listFiles只能列出文件的信息(而且提供递归遍历):访问时间、修改时间、块的位置、块的大小、所有者、所在组、路径、权限等等.
import java.net.URI;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;
public class hdfs_utils_1
{
public static void main(String[] args) throws Exception
{
Configuration config = new Configuration();
FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop11:9000/"), config,"dd_edw");
//listFiles只能列出文件的信息(而且提供递归遍历):访问时间、修改时间、块的位置、块的大小、所有者、所在组、路径、权限等等.
RemoteIterator listFiles = fileSystem.listFiles(new Path("/"), true);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //时间戳转化为时间.
while(listFiles.hasNext())
{
LocatedFileStatus file = listFiles.next();
System.out.printf("文件路径是:%s\n", file.getPath());
System.out.printf("文件名字:%s\n", file.getPath().getName());
System.out.printf("文件修改时间:%s\n", simpleDateFormat.format(new Date(file.getModificationTime())));
System.out.printf("文件访问时间:%s\n", simpleDateFormat.format(new Date(file.getAccessTime())));
System.out.printf("文件所有者:%s\n", file.getOwner());
System.out.printf("文件对应权限是:%s\n", file.getPermission());
System.out.printf("文件对应的块大小:%s 字节\n", file.getBlockSize());
System.out.printf("文件对应的大小:%s 字节\n", file.getLen());
System.out.printf("文件对应的副本数:%s 个\n", file.getReplication());
BlockLocation[] blockLocations = file.getBlockLocations();
System.out.printf("文件对应%s 个block块.",blockLocations.length);
for (BlockLocation blockLocation : blockLocations)
{
System.out.printf("blocks块对应的位置是:");
String[] hosts = blockLocation.getHosts();
for (String string : hosts)
{
System.out.println(string);
}
}
System.out.println("------------------------------");
}
}
}
第二:listStatus可以列出某个指定目录下面文件和文件夹的信息(但是不提供递归遍历):访问时间、修改时间、块的位置、块的大小、所有者、所在组、路径、权限等等.
public class hdfs_utils_1
{
public static void main(String[] args) throws Exception
{
Configuration config = new Configuration();
FileSystem fileSystem = FileSystem.get(
new URI("hdfs://hadoop11:9000/"), config, "dd_edw");
// listStatus可以列出某个指定目录下面文件和文件夹的信息(但是不提供递归遍历):访问时间、修改时间、块的位置、块的大小、所有者、所在组、路径、权限等等.
FileStatus[] listStatus = fileSystem.listStatus(new Path("/"));
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss"); // 时间戳转化为时间.
for (FileStatus fileStatus : listStatus)
{
System.out.printf("是否是文件夹:%s \n", fileStatus.isDirectory());
System.out.printf("是否是文件:%s \n", fileStatus.isFile());
System.out.printf("文件或者文件夹的路径是:%s\n", fileStatus.getPath());
System.out.printf("文件或者文件夹的名字:%s\n", fileStatus.getPath().getName());
System.out.printf("文件或者文件夹的修改时间:%s\n", simpleDateFormat.format(new Date(fileStatus.getModificationTime())));
System.out.printf("文件或者文件夹的修改时间:%s\n", simpleDateFormat.format(new Date(fileStatus.getAccessTime())));
System.out.printf("文件或者文件夹的修改时间:%s\n", fileStatus.getOwner());
System.out.printf("文件或者文件夹的权限是:%s\n", fileStatus.getPermission());
System.out.printf("文件或者文件夹的块大小:%s 字节\n", fileStatus.getBlockSize());
System.out.printf("文件或者文件夹的对应的大小:%s 字节\n", fileStatus.getLen());
System.out.printf("文件或者文件夹的对应的副本数:%s 个\n",fileStatus.getReplication());
//好像不能获取到block对应的host位置.
System.out.println("------------------------------");
}
}
}
public class WordCount
{
public static String path = "/user/mart_cfo/"; //文件夹后面加不加/无所谓.
public static void main(String[] args) throws IOException
{
Configuration config = new Configuration();
config.set("fs.default.name", "hdfs://hadoop11:9000");
FileSystem fileSystem = FileSystem.get(config);
//判断文件或者文件夹是否存在.
if (fileSystem.exists(new Path(path)))
{
System.out.printf("%s 路径已经存在!",path);
}
else {
System.out.printf("%s 路径不存在!",path);
}
}
}
对于以上问题,如有问题,欢迎留言指正!