hadoop版本:1.0.4,jdk:1.7.0_25 64bit。
在进行mahout算法分析的时候有时会遇到算法最后的输出文件是序列文件的情况下,这样就不能直接通过HDFS文件系统看到最终的结果了(乱码,因为是序列文件)。以前编写过一个可以直接把序列文件<key,value>读入到一个map变量中的java文件,叫做ReadArbiKV ,可以在http://download.csdn.net/detail/fansy1990/6453527看到。
但是上面的有个问题,就是当数据很大的时候,如果读不到一个map变量里面怎么办?
所以就可以使用下面的思路:一边读一边写。怎么个意思?直接读取序列文件的<key,value>,然后对key和value分别进行解析,最后直接进行输出。即每读取一行记录,解析一行,然后再输出一行。这样就不会有上面的问题了。
主程序是ReadAndWritePatterns,其中需要实现IKVRegex接口,这个接口是解析key和value的标准。给出的代码中的AKVRegex、ImplAKVRegex是这个接口的两个实现,可以参考,其中AKVRegex是什么都不做的,只是把原始的类.toString()而已,ImplAKVRegex是有一些操作的,原来是针对fpg算法的最后输出的解析的,但是好像有点不是很对。
下面给出一个调用demo:
package mahout.fansy.fpg; import java.io.IOException; import junit.framework.TestCase; import mahout.fansy.utils.fpg.AKVRegex; import mahout.fansy.utils.fpg.ImplAKVRegex; import mahout.fansy.utils.fpg.ReadAndWritePatterns ; public class TestReadAndWritePatterns extends TestCase { public void testReadAndWrite() throws IOException{ String input="hdfs://ubuntu:9000/user/mahout/fp/output/frequentpatterns/part-r-00000"; String output="hdfs://ubuntu:9000/user/mahout/fp/output_/01.txt"; String jobtracker="ubuntu:9001"; // AKVRegex regex=; ReadAndWritePatterns.readAndWritePatterns(input, output, jobtracker, new AKVRegex()); } }
主程序:ReadAndWritePatterns
package mahout.fansy.utils.fpg; import java.io.IOException; import java.net.URI; import org.apache.hadoop.conf.Configuration; 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.apache.hadoop.io.SequenceFile; import org.apache.hadoop.io.Writable; import org.apache.hadoop.util.ReflectionUtils; import org.apache.mahout.common.HadoopUtil; public class ReadAndWritePatterns { /* * 私有化 构造函数,只能使用方法调用 */ private ReadAndWritePatterns(){} /** * 读取<key,value>序列数据,写入HDFS文件系统 * @param input 输入序列文件 * @param output 输出HDFS文件(txt格式) * @param jobtracker 使用的jobtracker地址 * @param regex 使用的解析类,用于解析key和value * @return 任务是否成功 * @throws IOException */ public static boolean readAndWritePatterns(String input,String output,String jobtracker,AKVRegex regex) throws IOException{ boolean flag=true; Configuration conf=new Configuration(); conf.set("mapred.job.tracker", jobtracker); FileSystem fsIn = FileSystem.get(URI.create(input), conf); FileSystem fsOut = FileSystem.get(URI.create(output), conf); HadoopUtil.delete(conf, new Path(output)); Path pathIn = new Path(input); Path pathOut = new Path(output); SequenceFile.Reader reader = null; FSDataOutputStream out = fsOut.create(pathOut); try { reader = new SequenceFile.Reader(fsIn, pathIn, conf); Writable key = (Writable) ReflectionUtils.newInstance(reader.getKeyClass(), conf); Writable value = (Writable) ReflectionUtils.newInstance(reader.getValueClass(), conf); while (reader.next(key, value)) { // read String k=regex.keyRegex(key); String v=regex.valueRegex(value); // write if("".equals(v)||v==null){ continue; } out.writeChars(k+"\t"+v+"\n"); } } catch(IOException e){ flag=false; }finally { IOUtils.closeStream(reader); } return flag; } }IKVRegex接口:
package mahout.fansy.utils.fpg; import org.apache.hadoop.io.Writable; /** * <key,value>解析方法 * @author Administrator * */ public interface IKVRegex { /** * key 的解析方法 * @return key的解析字符串 */ public String keyRegex(Writable key); /** * value 的解析方法 * @return value的解析字符串 */ public String valueRegex(Writable value); }
package mahout.fansy.utils.fpg; import org.apache.hadoop.io.Writable; public class AKVRegex implements IKVRegex{ /** * key 的解析方法 * @return key的解析字符串 */ public String keyRegex(Writable key){ return key.toString(); }; /** * value 的解析方法 * @return value的解析字符串 */ public String valueRegex(Writable value) { return value.toString(); } }
package mahout.fansy.utils.fpg; import org.apache.hadoop.io.Writable; import org.apache.mahout.fpm.pfpgrowth.convertors.string.TopKStringPatterns; /** * 用于解析fpg算法输出的频繁项目集 * @author Administrator * */ public class ImplAKVRegex implements IKVRegex{ /** * value 的解析方法 * @return value的解析字符串 */ public String valueRegex(Writable value) { TopKStringPatterns val=(TopKStringPatterns) value; String temp=val.toString(); if(val.getPatterns().size()==1){ return ""; }else{ int b=temp.indexOf(")"); return temp.substring(b+2,temp.length()); } } @Override public String keyRegex(Writable key) { // TODO Auto-generated method stub return key.toString(); } }
分享,成长,快乐
转载请注明blog地址:http://blog.csdn.net/fansy1990