环境配置
eclipse配置hdfs的环境
- hadoop的插件hadoop-eclipse-plugin,放在eclipse的安装目录的plugins下
配置本地hadoop的环境
- 解压hadoop安装包
- 配置windows下hadoop的环境变量
- 新建:HADOOP_HOME=hadoop的解压路径,我的是:HADOOP_HOME=C:\soft\hadoop-2.7.6
- 在path下加上%HADOOP_HOME%bin;%HADOOP_HOME%sbin
- 配置windows下hadoop的相关插件
- hadoop.dll放在C:\Windows\System32下
- winutils.exe放在hadoop的安装目录的bin目录下
- 重启eclipse
- 配置eclipse可视化界面:
- 启动eclipse;
- windows下搜索hadoop,把hadoop的安装目录导过来,点击确定,应用
- windows下showview选择other搜索mapreduce的location(配置之前保证hadoop集群是启动的)
- 右键—new hadoop location —
- location name = 可以任意指定
- 左边指的是yarn的master,我的是:host:dadoop04,port:9001( 注意,需要提前在路径C:\Windows\System32\drivers\etc\hosts下配置好主机映射)
- 右边是hdfs的主节点dfsmaster:dfsmaster的host:hadoop02,port:9000
- username是登陆集群的用户名,我的是:hadoop
- eclipse的可视化界面配置完成之后会出现一个DFS location
java项目中添加依赖:
- 项目下面建包:lib下的buildpath。
- 好处:代码移动的时候比较方便,联通依赖包一起移动
- 缺点:会造成工程很臃肿,jar包冲突
- maven添加依赖
- 好处:代码比较轻便,自动解决jar包冲突的问题
- 缺点:代码移动的时候,需要重新构建
- 创建本地用户依赖库
代码
1.测试hdfs的链接是否成功1
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
/**
* 测试hdfs的链接是否成功
* @author dai
*
*/
public class testHdfs {
public static void main(String[] args) throws IOException {
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(conf);
System.out.println(fs);
/**
* 参数1:本地的文件路径
* 参数2:
*/
Path src=new Path("C:\\soft\\hadoop-2.7.6\\LICENSE.txt");
Path dst=new Path("/testxxxx_tmp");
fs.copyFromLocalFile(src, dst);
}
}
2.测试hdfs的链接是否成功2
import java.io.IOException;
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.hdfs.DistributedFileSystem;
/**
* 测试hdfs的链接是否成功
* @author dai
*
*/
public class testHdfs2 {
public static void main(String[] args) throws IOException, InterruptedException, URISyntaxException {
/**
* 文件上传成功了,提前设定集群中的副本为2个, 通过这种方式上传的文件的副本还是3个,为什么?
*因为这里加载的配置文件,不是集群的,而代码中jar包中的。
* 这里的conf对象默认加载的是hadoop-hdfs-2.7.6.jar包下的hdfs-default.xml文件
* conf对象就是加载以下配置文件
* hdfs-default.xml
* core-default.xml
* yarn-default.xml
* mapred-default.xml
* hdfs-site.xml
* core-site.xml
* yarn-site.xml
* mapred-site.xml
* conf对象加载配置文件的时候,加载次序:
* jar包下加载》》》》src下加载》》》》 hdfs-default.xml hdfs-site.xml>>>代码中的
* 生效的顺序:
* 代码中的》》》》src下的》》》》jar包中的
*
*/
Configuration conf=new Configuration();
/**
* 在配置文件中,两个参数是k-v形式存在的
* <property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop01:9000</value>
</property>
key:<name>fs.defaultFS</name>
value:<value>hdfs://hadoop01:9000</value>
设置分布式文件系统的入口
*/
/**
* 参数1:hdfs集群连接的主节点入口
*/
FileSystem fs=FileSystem.get(new URI("hdfs://hadoop01:9000"), conf, "hadoop");
System.out.println(fs instanceof DistributedFileSystem);
/**
* 修改权限的集中方式:
* 1)代码提交的时候进行设置参数
* 右键》》》》run as>>>> run configurations
* arguments>>>>>>>
* program arguments:代码中需要的参数 String[] args
* VM arguments: 代码运行中 jvm的参数
* jvm提交代码的时候的用户
* 将用户名已添加上
* -DHADOOP_USER_NAME=hadoop
* 2)在代码中添加:
* conf.set("HADOOP_USER_NAME", "hadoop");
*
* System.setProperty("HADOOP_USER_NAME", "hadoop");
* FileSystem fs=FileSystem.get(new URI("hdfs://hadoop01:9000"), conf, "hadoop");
* 3) 在windows的环境变量中
* HADOOP_USER_NAME=hadoop
*
*如果代码中和运行的时候都指定了用户名:
*先加载运行指定的参数 在加载代码中,代码中的参数会覆盖掉运行指定的参数
*最后生效的是代码中的
*/
Path src=new Path("/cc/testcrc");
Path dst=new Path("C:\\test_crc_04");
/**
* 文件上传成功之后会生成两个文件 :原始文件、CRC文件
* linux下查看一下:
* blk_1073741825 原始文件
blk_1073741825_1001.meta 元数据文件----crc文件 校验 存储的是原始文件的偏移量
校验数据的完整性 验证数据是否被修改了或损坏了 校验的时候与文件上传的时候的数据进行校验
* 1)块的末尾追加不会影响校验
* 2)块的中间追加,会影响校验,产生校验和错误
* 结论:crc校验,从原始文件头---原始文件末尾 的校验,如果这部分内容不发生改变,不会影响校验 这部分内容发生改变的修啊吧则会报校验和错误 。
*
* Exception in thread "main" org.apache.hadoop.fs.ChecksumException: Checksum error: /cc/testcrc at 0 exp: 1139544428 got: -1322830295
* 文件块损坏的异常
*/
fs.copyToLocalFile(src, dst);
}
}
3.用流的方式进行文件上传和下载
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
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;
/**
* 用流的方式进行文件上传和下载
* @author dai
*
*/
public class testHdfsStream {
public static void main(String[] args) throws IOException, InterruptedException, URISyntaxException {
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(new URI("hdfs://hadoop01:9000"), conf, "hadoop");
FSDataInputStream in01 = fs.open(new Path("/testcrc01"));
in01.seek(5);
FileOutputStream out01=new FileOutputStream("C:\\testcrc03");
IOUtils.copyBytes(in01, out01, 4096, true);
fs.close();
}
}
4.创建,删除,上传,下载文件等api操作
import java.io.IOException
import java.net.URI
import java.net.URISyntaxException
import java.util.Arrays
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
public class testHdfsDemo01 {
public static void main(String[] args) throws InterruptedException, URISyntaxException, IOException {
Configuration conf=new Configuration()
FileSystem fs=FileSystem.get(new URI("hdfs://hadoop01:9000"),conf,"hadoop")
//创建文件夹:级联创建,相当于hadoop fs -mkdir -p
//删除文件夹:文件 空目录 非空目录
//fs.delete(new Path("/cc"))
//参数1:删除的路径 参数2:是否递归删除 true 需要递归 false:不递归
//fs.delete(new Path("/xxxx"), true)
//查看指定目录下的文件信息,相当于hadoop fs -ls /
RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), false)
//循环遍历输出
while(listFiles.hasNext()){
//System.out.println(listFiles.next())
//LocatedFileStatus 描述hdfs上的文件或目录信息的对象
LocatedFileStatus next = listFiles.next()
System.out.println(next.getPath())
System.out.println(next.getLen())
System.out.println(next.getBlockSize())
BlockLocation[] blockLocations = next.getBlockLocations()
System.out.println("999999999999999999999999999999")
for(BlockLocation bl:blockLocations){
System.out.println(bl.getOffset())
System.out.println(bl.getLength())
System.out.println(Arrays.toString(bl.getHosts()))
}
}
//获取状态信息 返回的是状态信息对象 FileStatus 封装的是一个路径的信息
//这种方式只能返回文件或目录的状态信息 不能返回块信息 获取文件或目录的信息都可以
fs.close()
}
}