验证中...
FileHandler.java
Raw Copy
package n_merge;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* 文件处理
* @author Administrator
*
*/
public class FileHandler {
private static int n=10;
static String spiltfileName="spilt_file";
/**将大文件分割成小文件*/
public static int splitFile(String url,String filename) throws Exception{
//获得文件总行数
Integer lines = getTxtLines(url,filename);
int nLine=lines/n;
int rline=lines%n;
int l=rline==0? 0:1;
n=n+l;
//随机文件访问类
RandomAccessFile r=new RandomAccessFile(url+"\\"+filename,"r");
for(int i=1;i<=n;i++){
//第i个文件分割开始位置和结束位置
int startLine=(i-1)*nLine+1;
int endLine=i==n&&l!=0? startLine+rline-1:startLine+nLine-1;
//创建单个小文件
createSingleTxt(r, startLine, endLine, url, spiltfileName+i+".txt");
}
r.close();
return n;
}
/**获取文件的总行数*/
private static Integer getTxtLines(String url,String filename) throws Exception{
//BufferReader可以读取一行
BufferedReader r=new BufferedReader(new FileReader(url+"\\"+filename));
Integer line=0;
while(r.readLine()!=null){
line++;
}
r.close();
return line;
}
/**生成单个小文件*/
private static void createSingleTxt(RandomAccessFile r,Integer sline,Integer eline,String url,String outFilename) throws IOException{
List<String[]> list=new LinkedList<>();
//打印流,可以打印一行并且换行
PrintWriter pw=new PrintWriter(url+"\\"+outFilename);
String lstr;
while((sline++<=eline)&&(lstr=r.readLine()) != null){
//转换成UTF-8编码
lstr=new String(lstr.getBytes("iso8859-1"),"utf-8");
//以空格为分隔符分割,目的在于将字段分开
String[] strs = lstr.split("\t");
list.add(strs);
}
//策略模式,其思想是针对一组算法,将每一种算法封装到具有共同的独立类中,从而是他们可以相互替换
Collections.sort(list,new Comparator<String[]>() {
@Override
public int compare(String[] o1, String[] o2) {
//下标12 刚好是注册时间,按注册时间降序
Integer s1="".equals(o1[12])? 0:Integer.valueOf(o1[12].replace("\"", ""));
Integer s2="".equals(o2[12])? 0:Integer.valueOf(o2[12].replace("\"", ""));
return -s1.compareTo(s2);
}
});
for(int i=0;i<list.size();i++){
if(i>0){
pw.println();
}
pw.print(containStr(list.get(i)));
}
pw.close();
}
//将分割的字符串数组以\t为分割符组装成字符串
private static String containStr(String[] strs){
StringBuilder sb=new StringBuilder("");
for(int i=0;i<strs.length;i++){
if(i>0){
sb.append("\t");
}
sb.append(strs[i]);
}
return sb.toString();
}
public static void init(int newN,String newSpiltfileName){
n=newN;
spiltfileName=newSpiltfileName;
}
}
FileQueueHandler.java
Raw Copy
package n_merge;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.RandomAccessFile;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
/**
* 队列处理
* @author Administrator
*
*/
public class FileQueueHandler {
/**编号+每个文件的队列*/
public static Map<Integer,Deque<String[]>> queues=new HashMap<>();
/**每个文件读到多少行*/
private static Map<Integer,Integer> readLineMap;
/**每个文件访问到文件随机访问类访问到指针位置*/
public static Map<Integer,Long> readIndexMap;
/**
* 生成队列
* @param n-分割文件个数 m-每个队列最大元素个数
* @throws Exception
*/
public static void createQueue(int n,int m,String url) throws Exception{
//编号
init(n);
for(int i=1;i<=n;i++){
initSingleQueue(i, url, m);
}
}
/**
* 初始化每个文件的队列
* @param n 文件编号
* @param url 文件路径
* @param m 队列中元素最大个数
* @throws Exception
*/
private static void initSingleQueue(int n,String url,int m) throws Exception{
Deque<String[]> queue=new ArrayDeque<>();
RandomAccessFile raf=new RandomAccessFile(url+"\\"+FileHandler.spiltfileName+n+".txt","r");
int l=0;
String str=new String();
while(((++l)<=m)&&(str=raf.readLine())!=null){
String[] strs=str.split("\t");
queue.offer(strs);
queues.put(n, queue);
}
if(l>0){
readLineMap.put(n, --l);
readIndexMap.put(n, raf.getFilePointer());
}
raf.close();
}
/**
* 为队列添加新元素
* @param n 文件编号
* @param url
* @return
* @throws Exception
*/
public static Map<Integer,Deque<String[]>> readNewLine(int n,String url) throws Exception{
RandomAccessFile raf=new RandomAccessFile(url+"\\"+FileHandler.spiltfileName+n+".txt","r");
raf.seek(readIndexMap.get(n));
String str=new String();
if((str=raf.readLine())!=null){
if(str==null||"".equals(str)){
System.out.println(readIndexMap.get(n)+" "+n);
}
String[] strings = str.split("\t");
queues.get(n).add(strings);
long v = raf.getFilePointer();
readIndexMap.put(n, v);
}
raf.close();
return queues;
}
private static void init(int n){
readLineMap=new HashMap<>();
readIndexMap=new HashMap<>();
for(int i=1;i<=n;i++){
readLineMap.put(i, 0);
readIndexMap.put(i,(long) 0);
}
}
}
Member.java
Raw Copy
package n_merge;
public class Member {
private Integer id;
// 用户名
private String userName;
// 用户头像
private String userPhoto;
// 密码
private String userPass;
// 用户类型 1:个人用户;2:企业用户;3:平台账户
private Byte userType;
// 邮箱
private String userEmail;
// 手机号
private String userPhone;
// 用户等级
private Byte userLevel;
// 会员等级最新生效时间
private Integer levelActiveTime;
// 会员等级持续降级天数
private Integer degradeDays;
// 经验值
private Long credits;
// 积分
private Long scores;
// 注册时间
private Integer regTime;
// 注册IP
private String regIp;
// 推荐人UID
private Integer recommendId;
// 推广码
private String expandNum;
// 专属客服
private Long delicatedCustomer;
// 用户来源 web;wap;ios;android
private String platform;
// 用户注册上一个页面地址
private String regFromSeo;
// 注册来源平台
private String userFrom;
// 法大大Id
private String fadadaId;
// 开启自动签署合同Id
private Integer autoSignContractId;
// 是否自动签署合同 0:否;1:是
private Byte autoSignContract;
// 借款人自动签署合同id
private Integer borrowerAutoSignContractId;
// 个推使用clientid来标识每个独立的用户
private String clientId;
// 盐值
private String salt;
// 用户名修改次数
private Integer usernameUpdateTime;
// 免费提现次数
private Integer freeWithdrawNum;
//百度SEM推广码
private String promote;
//APP分渠道统计码
private String channel;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPhoto() {
return userPhoto;
}
public void setUserPhoto(String userPhoto) {
this.userPhoto = userPhoto;
}
public String getUserPass() {
return userPass;
}
public void setUserPass(String userPass) {
this.userPass = userPass;
}
public Byte getUserType() {
return userType;
}
public void setUserType(Byte userType) {
this.userType = userType;
}
public String getUserEmail() {
return userEmail;
}
public void setUserEmail(String userEmail) {
this.userEmail = userEmail;
}
public String getUserPhone() {
return userPhone;
}
public void setUserPhone(String userPhone) {
this.userPhone = userPhone;
}
public Byte getUserLevel() {
return userLevel;
}
public void setUserLevel(Byte userLevel) {
this.userLevel = userLevel;
}
public Integer getLevelActiveTime() {
return levelActiveTime;
}
public void setLevelActiveTime(Integer levelActiveTime) {
this.levelActiveTime = levelActiveTime;
}
public Integer getDegradeDays() {
return degradeDays;
}
public void setDegradeDays(Integer degradeDays) {
this.degradeDays = degradeDays;
}
public Long getCredits() {
return credits;
}
public void setCredits(Long credits) {
this.credits = credits;
}
public Long getScores() {
return scores;
}
public void setScores(Long scores) {
this.scores = scores;
}
public Integer getRegTime() {
return regTime;
}
public void setRegTime(Integer regTime) {
this.regTime = regTime;
}
public String getRegIp() {
return regIp;
}
public void setRegIp(String regIp) {
this.regIp = regIp;
}
public Integer getRecommendId() {
return recommendId;
}
public void setRecommendId(Integer recommendId) {
this.recommendId = recommendId;
}
public String getExpandNum() {
return expandNum;
}
public void setExpandNum(String expandNum) {
this.expandNum = expandNum;
}
public Long getDelicatedCustomer() {
return delicatedCustomer;
}
public void setDelicatedCustomer(Long delicatedCustomer) {
this.delicatedCustomer = delicatedCustomer;
}
public String getPlatform() {
return platform;
}
public void setPlatform(String platform) {
this.platform = platform;
}
public String getRegFromSeo() {
return regFromSeo;
}
public void setRegFromSeo(String regFromSeo) {
this.regFromSeo = regFromSeo;
}
public String getUserFrom() {
return userFrom;
}
public void setUserFrom(String userFrom) {
this.userFrom = userFrom;
}
public String getFadadaId() {
return fadadaId;
}
public void setFadadaId(String fadadaId) {
this.fadadaId = fadadaId;
}
public Integer getAutoSignContractId() {
return autoSignContractId;
}
public void setAutoSignContractId(Integer autoSignContractId) {
this.autoSignContractId = autoSignContractId;
}
public Byte getAutoSignContract() {
return autoSignContract;
}
public void setAutoSignContract(Byte autoSignContract) {
this.autoSignContract = autoSignContract;
}
public Integer getBorrowerAutoSignContractId() {
return borrowerAutoSignContractId;
}
public void setBorrowerAutoSignContractId(Integer borrowerAutoSignContractId) {
this.borrowerAutoSignContractId = borrowerAutoSignContractId;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public Integer getUsernameUpdateTime() {
return usernameUpdateTime;
}
public void setUsernameUpdateTime(Integer usernameUpdateTime) {
this.usernameUpdateTime = usernameUpdateTime;
}
public Integer getFreeWithdrawNum() {
return freeWithdrawNum;
}
public void setFreeWithdrawNum(Integer freeWithdrawNum) {
this.freeWithdrawNum = freeWithdrawNum;
}
public String getPromote() {
return promote;
}
public void setPromote(String promote) {
this.promote = promote;
}
public String getChannel() {
return channel;
}
public void setChannel(String channel) {
this.channel = channel;
}
@Override
public String toString() {
return "\"" + id + "\" \"" + userName + "\" \"" + userPhoto + "\" \"" + userPass
+ "\" \"" + userType + "\" \"" + userEmail + "\" \"" + userPhone + "\" \""
+ userLevel + "\" \"" + levelActiveTime + "\" \"" + degradeDays + "\" \""
+ credits + "\" \"" + scores + "\" \"" + regTime + "\" \"" + regIp + "\" \""
+ recommendId + "\" \"" + expandNum + "\" \"" + delicatedCustomer + "\" \""
+ platform + ", regFromSeo=" + regFromSeo + ", userFrom=" + userFrom + ", fadadaId=" + fadadaId
+ "\" \"" + autoSignContractId + "\" \"" + autoSignContract
+ "\" \"" + borrowerAutoSignContractId + "\" \"" + clientId + "\" \""
+ salt + "\" \"" + usernameUpdateTime + "\" \"" + freeWithdrawNum
+ "\" \"" + promote + "\" \"" + channel + "\"";
}
}
TransferStation.java
Raw Copy
package n_merge;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class TransferStation {
private static int n;
private static Object[] topN;
private static List<String[]> cache;
private static int maxCacheSize=20;
private static String tempFileName="temp";
private static String url;
private static Map<Integer, Deque<String[]>> queues;
private static PrintWriter pw;
public static void init(int pn,String pUrl){
n=pn;
url=pUrl;
queues = FileQueueHandler.queues;
getTopN();
cache=new ArrayList<>(maxCacheSize);
}
public static void transfer() throws Exception{
while(true){
int mark = comparator();
if(mark==0){
File file=new File(url+"\\"+tempFileName+".txt");
PrintWriter pw=new PrintWriter(new FileOutputStream(file,true));
for(String[] e:cache){
String splicing = splicing(e);
splicing=new String(splicing.getBytes("iso8859-1"),"utf-8");
pw.println(splicing);
}
pw.close();
cache.clear();
break;
}
//通知响应队列
Deque<String[]> deque = queues.get(mark);
String[] pop = deque.pop();
queues.put(mark, deque);
//去掉一条元素,从文件中获取一条新元素
queues= FileQueueHandler.readNewLine(mark, url);
topN[mark]=queues.get(mark).peek();
cache.add(pop);
//刷新缓存
refresh();
}
}
/**获得每个队列的队头元素*/
private static void getTopN(){
topN=new Object[n+1];
Map<Integer, Deque<String[]>> queues = FileQueueHandler.queues;
for(Entry<Integer, Deque<String[]>> entry:queues.entrySet()){
Integer key = entry.getKey();
Deque<String[]> deque = entry.getValue();
topN[key]=deque.peek();
}
}
/**获得topN中最大元素编号*/
private static int comparator(){
int mark=0;
try {
String[] maxElement=(String[]) topN[1];
Integer maxC=0;
if(maxElement!=null&&maxElement.length>12){
maxC=maxElement[12].equals("")? 0:Integer.valueOf(maxElement[12].replace("\"", ""));
mark=1;
}
for(int i=1;i<=n;i++){
String[] current = (String[]) topN[i];
if(current==null||current.length<13){
continue;
}
Integer c = current[12].equals("")? 0:Integer.valueOf(current[12].replace("\"", ""));
if(maxC<c){
mark=i;
maxElement=(String[]) topN[i];
maxC=c;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return mark;
}
private static void refresh() throws Exception{
if(cache.size()==maxCacheSize){
File file=new File(url+"\\"+tempFileName+".txt");
pw=new PrintWriter(new FileOutputStream(file,true));
for(String[] e:cache){
String splicing = splicing(e);
splicing=new String(splicing.getBytes("iso8859-1"),"utf-8");
pw.println(splicing);
pw.flush();
}
pw.close();
cache.clear();
}
}
private static String splicing(String[] strs){
StringBuilder sb=new StringBuilder();
for(String str:strs){
if(sb.length()>0){
sb.append("\t");
}
sb.append("").append(str).append("");
}
return sb.toString();
}
}
Client.java
Raw Copy
package n_merge;
/**
* N路归并排序 按注册时间降序
* @author Administrator
* 坑:用递归×,'\t\n'(ノへ ̄、),文件随机访问流-文件指针≡(▔﹏▔)≡
* 数据量大,递归次数多,导致栈溢出,原因本地方法栈内存被占满
*/
public class Client {
static int n=10;
public static void main(String[] args) throws Exception {
//分割文件
FileHandler.init(10, "spilt_file");
int n = FileHandler.splitFile("F:\\n_merge","p2p_member.txt");
//生成队列
FileQueueHandler.createQueue(n, 10, "F:\\n_merge");
//中转站
TransferStation.init(n, "F:\\n_merge");
TransferStation.transfer();
}
}
N归并排序.png

Comment list( 0 )

You need to Sign in for post a comment

Help Search