hadoop学习day2开发笔记

1、将hdfs客户端开发所需的jar导入工程(jar包可在hadoop安装包中找到common/hdfs)

2、写代码

要对hdfs中的文件进行操作,代码中首先需要获得一个hdfs的客户端对象

Configuration conf = new Configuration();

FileSystem fs = FileSystem.get(new URI("hdfs://hdp-01:9000"),conf,"root");

 

  FilenameFilter过滤文件

// 列出日志源目录中满足条件的文件
File[] listFiles = srcDir.listFiles(new FilenameFilter() {

@Override
public boolean accept(File dir, String name) {
    if (name.startsWith("aaa"))) {
        return true;
}
    return false;
}
});
        

 

用renameTo来实现移动文件

如果被重命名的文件已存在,那么renameTo()不会成功
renameTo()成功后,原文件会被删除

apache的commons的FileUtils类实现移动文件

import org.apache.commons.io.FileUtils;
FileUtils.moveFileToDirectory(file, toUploadDir, true);

 hdfs内部移动文件用rename

 

配置参数用单例,内存保存一个不反复读取

 

/**
 * 单例模式:懒汉式——考虑了线程安全
 * @author ThinkPad
 *
 */

public class PropertyHolderLazy {

    private static Properties prop = null;

    public static Properties getProps() throws Exception {
        if (prop == null) {
            synchronized (PropertyHolderLazy.class) {
                if (prop == null) {
                    prop = new Properties();
                    prop.load(PropertyHolderLazy.class.getClassLoader().getResourceAsStream("collect.properties"));
                }
            }
        }
        return prop;
    }

}

 

InputStream类以及子类中的Read方法

Read方法

read()

public  abstract  int  read() throws IOException
从(来源)输入流中(读取的内容)读取数据的下一个字节到(去处)java程序内部中
返回值为0到255的int类型的值,返回值为字符的ACSII值(如a就返回97,n就返回110).
如果没有可用的字节,因为已经到达流的末尾, -1返回的值

运行一次只读一个字节,所以经常与while((len = inputstream.read()) != -1)一起使用

 

read(byte [] b )

public int read(byte[] b) throws IOException
从(来源)输入流中(读取内容)读取的一定数量字节数,并将它们存储到(去处)缓冲区数组b中

返回值为实际读取的字节数

运行一次读取一定的数量的字节数.java会尽可能的读取b个字节,但也有可能读取少于b的字节数.至少读取一个字节

第一个字节存储读入元素b[0],下一个b[1],等等。读取的字节数是最多等于b的长度。

如果没有可用的字节,因为已经到达流的末尾, -1返回的值 

如果b.length==0,则返回0

 

read( byte [] b , int off , int len)

public int read(byte[] b, int off, int len,    throws IOException)
读取 len字节的数据从输入流到一个字节数组。

试图读取多达 len字节,但可能读取到少于len字节。返回实际读取的字节数为整数。 

第一个字节存储读入元素b[off],下一个b[off+1],等等。读取的字节数是最多等于len。k被读取的字节数,这些字节将存储在元素通过b[off+k-1]b[off],离开元素通过b[off+len-1]b[off+k]未受影响。

read(byte[]b)就是相当于read(byte [] b , 0 , b.length).所以两者差不多.性质一样
---------------------
作者:CarpricornMrJi
来源:CSDN
原文:https://blog.csdn.net/qq_37835596/article/details/76559572
版权声明:本文为博主原创文章,转载请附上博文链接!

 

往hdfs中的文件写内容

/**
     * 往hdfs中的文件写内容
     * 
     * @throws IOException
     * @throws IllegalArgumentException
     */

    @Test
    public void testWriteData() throws IllegalArgumentException, IOException {

        FSDataOutputStream out = fs.create(new Path("/zz.jpg"), false);
     //读本地文件写入hdfs
        FileInputStream in = new FileInputStream("D:/images/006l0mbogy1fhehjb6ikoj30ku0ku76b.jpg");

        byte[] buf = new byte[1024];
        int read = 0;
        while ((read = in.read(buf)) != -1) {
            out.write(buf,0,read);//最后一个,buffer只有前一部分是新读的数据
        }
        
        in.close();
        out.close();
        fs.close();

    }

 

 

面向接口编程

//定义接口
public interface Mapper {
    
    
    public void map(String line,Context context);
    

}

 

//数据存储对象
public class Context {
    
    private HashMap<Object,Object> contextMap = new HashMap<>();
    
    public void write(Object key,Object value){
        
        contextMap.put(key, value);
        
    }
    
    
    public Object get(Object key){
        
        return contextMap.get(key);
        
    }
    
    public HashMap<Object,Object> getContextMap(){
        return contextMap;
    }
    
    

}

 

//实现接口
public class WordCountMapper implements Mapper{

    @Override
    public void map(String line, Context context) {
        
        String[] words = line.split(" ");
        
        for (String word : words) {
            
            Object value = context.get(word);
            if(null==value){
                context.write(word, 1);
                
            }else{
                int v = (int)value;
                context.write(word, v+1);
            }
            
            
            
        }
        
        
        
    }

}

 

//新建文件job.properties,类不能带引号,需要更换调用方法时只要新建类实现接口,再修改此处即可
MAPPER_CLASS=cn.edu360.hdfs.wordcount.WordCountMapper 

 

//实例化具体类
Class<?> mapper_class = Class.forName(props.getProperty("MAPPER_CLASS"));
Mapper mapper = (Mapper) mapper_class.newInstance();
Context context  =  new Context();

 

// 调用方法进行业务处理
mapper.map(line, context);

 

posted @ 2019-01-14 09:21  喵喵帕斯  阅读(163)  评论(0编辑  收藏  举报