hadoop-day1-切分文件
java模拟切分文件
package com.shujia; import java.io.*; import java.util.ArrayList; public class SplitFileBlock { public static void main(String[] args) throws Exception { //将数据读取进来 //字符缓冲输入流 BufferedReader br = new BufferedReader(new FileReader("data/students.txt")); int index = 0; //字符缓冲输出流 BufferedWriter bw = new BufferedWriter(new FileWriter("data/blocks2/block---" + index)); //现在是假设一行数据是1m,没128m数据,就生成一个block块,不到128m也会生成一个block块 //每次读到128*1.1约等于140行的数据,就写入128行,剩下的12行计入下一次block块中去存储 //定义一个集合,用于存储,读取的内容 ArrayList<String> row = new ArrayList<>(); String line = null; //定义一个变量,记录读取的行数 int offset = 0; //定义一个变量,记录读取的是哪一个block块 int rowNum = 0; while ((line = br.readLine()) != null) { row.add(line); offset++; //当我们的偏移量,128*1.1约等于140行的数据,就写入128行,剩下的12行计入下一次block块中去存储 if (offset == 140) { rowNum = 128 * index; //循环128次,将集合存储的数据,写入到block块中 for (int i = rowNum; i <= rowNum + 127; i++) { String s = row.get(i); bw.write(s); bw.newLine(); bw.flush(); } index++; //将offset设置为12 offset = 12; bw = new BufferedWriter(new FileWriter("data/blocks2/block---" + index)); } } //把剩余的数据写到一个block块中 for(int i = row.size()-offset;i<row.size();i++){ String s = row.get(i); bw.write(s); bw.newLine(); bw.flush(); } //释放资源 bw.close(); br.close(); } }
hadoop用java实现
map任务
package com.shujia; import java.io.*; import java.util.HashMap; import java.util.Map; import java.util.Set; public class MapTask implements Runnable { private File file; public int offset; public MapTask(File file,int offset) { this.file = file; this.offset = offset; } @Override public void run() { //字符缓冲输入流 try { BufferedReader br = new BufferedReader(new FileReader(file)); //创建一个Map集合,使用HashMap HashMap<String, Integer> map = new HashMap<>(); String line = null; while ((line = br.readLine()) != null) { //用逗号进行切分 String clazz = line.split(",")[4]; //如果在map中没有该班级作为key,那我们就把这个班级作为key存放在集合,value设置为1 if (!map.containsKey(clazz)) { map.put(clazz, 1); } else { //否则value值加1 map.put(clazz, map.get(clazz) + 1); } } //结束读取数据流程 br.close(); //将局部的map任务结果写入到文件中 //创建字符缓冲输出流 BufferedWriter bw = new BufferedWriter(new FileWriter("data/parts2/part---" + offset)); //遍历HashMap Set<Map.Entry<String, Integer>> entries = map.entrySet(); for (Map.Entry<String, Integer> keyValue : entries){ String clazz = keyValue.getKey(); Integer sumNumber = keyValue.getValue(); //写入文件 bw.write(clazz+":"+sumNumber); //换行 bw.newLine(); bw.flush(); } //关闭写通道 bw.close(); } catch (Exception e) { e.printStackTrace(); } } }
map任务执行
package com.shujia; import java.io.File; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /* Map(通过线程池的方式,简单来说,模拟hadoop中一个block块生成一个map任务,一个map任务相当于一个线程) (将切分出来的bolck块中,统计每个班级的人数) 4423毫秒 */ public class Map { public static void main(String[] args) { long start = System.currentTimeMillis(); //创建一个线程池 ExecutorService executorService = Executors.newFixedThreadPool(10000); File file = new File("data/blocks2"); //定义一个文件编号,从0开始 int offset = 0; File[] files = file.listFiles(); for (File f : files) { MapTask mapTask = new MapTask(f, offset); executorService.submit(mapTask); offset++; } //关闭线程池 executorService.shutdown(); long end = System.currentTimeMillis(); System.out.println("总耗时:"+(end - start)+"毫秒"); } }
reduce任务
package com.shujia; import java.io.*; import java.util.HashMap; import java.util.Map; import java.util.Set; //306毫秒 537毫秒 == 843毫秒 //4423毫秒reduce总耗时:117551毫秒 /* 模拟hadoop的切分map-reduce处理的方式,总耗时14毫秒 将每个map任务的结果,再做一次总的聚合,统计出最终的班级人数 当数据量过大的时候,TB以上的级别的时候 1、一台服务器不够存 2、可能一台够存,但是纯java程序是由JVM虚拟机调起的,内存有限,可能会导致,OOM内存溢出 这时候,就必须使用分布式存储,将大文件进行切分,先局部做运算,这时候局部的数据少很多,然后再总的聚合,数据量少且块! */ public class Reduce { public static void main(String[] args) throws Exception { long start = System.currentTimeMillis(); //将past目录封装成File对象 File file = new File("data/parts2"); //获取下面的所有文件对象数组 File[] files = file.listFiles(); //创建一个map集合,接收总的结果数据 HashMap<String, Integer> map = new HashMap<>(); //遍历每个part文件 for (File f : files) { //读取文件,进行分割 //创建缓冲字符输入流对象 BufferedReader br = new BufferedReader(new FileReader(f)); String line = null; while ((line = br.readLine()) != null) { //以冒号进行分割得到班级和人数 String[] strings = line.split(":"); String clazz = strings[0]; //包装类 Integer sum = Integer.valueOf(strings[1]); //判断map集合中是否存在对应的key if (!map.containsKey(clazz)) { map.put(clazz, sum); } else { //如果存在,value值相加 map.put(clazz, map.get(clazz) + sum); } } //关闭读取数据的通道 br.close(); } //将结果写入到最终一个文件 BufferedWriter bw = new BufferedWriter(new FileWriter("data/result-big/part-r-000000")); //遍历集合 Set<Map.Entry<String, Integer>> entries = map.entrySet(); for (Map.Entry<String, Integer> keyValue:entries){ String clazz = keyValue.getKey(); Integer number = keyValue.getValue(); bw.write(clazz+":"+number); bw.newLine(); bw.flush(); } //释放资源 bw.close(); long end = System.currentTimeMillis(); System.out.println("reduce总耗时:"+(end-start)+"毫秒"); } }
使用java程序模拟hadoop切分文件,统计students文件中,姓名包含’白’汉字的人数。
import java.io.*; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Set; public class Demo { public static void main(String[] args) { //将文件切分,写入blocks try { int index = 0; BufferedReader br = new BufferedReader(new FileReader("D:\\soft\\projects\\untitled\\data\\students.txt")); BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\soft\\projects\\untitled\\blocks\\block--" + index)); ArrayList<String> list = new ArrayList<>(); int offset = 0; int num = 0; String line = null; while ((line = br.readLine()) != null) { list.add(line); offset++; num = 128 * index; if (offset == 140) { for (int i = num; i <= num + 127; i++) { String s = list.get(i); bw.write(s); bw.newLine(); bw.flush(); } offset = 12; index++; bw = new BufferedWriter(new FileWriter("D:\\soft\\projects\\untitled\\blocks\\block--" + index)); } } for (int i = list.size() - offset; i < list.size(); i++) { String s = list.get(i); bw.write(s); bw.newLine(); bw.flush(); } bw.close(); br.close(); } catch (Exception e) { e.printStackTrace(); } } }
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; public class DemoTest { public static void main(String[] args) { //获取名字中有“白”的学生人数 File file = new File("D:\\soft\\projects\\untitled\\blocks"); File[] files = file.listFiles(); int index = 0; for (File s : files) { try { BufferedReader br = new BufferedReader(new FileReader(s)); String line = null; while ((line = br.readLine()) != null) { String[] split = line.split(","); if (split[1].contains("白")) { index++; } } br.close(); } catch (Exception e) { e.printStackTrace(); } } System.out.println("名字中含有“白”的有:"+index); } }