对文件每行的内容进行重排序

**
 * 功能:对文件每行的内容进行重排序,排序规则如下:
 *     文件中的数据是以空格为分隔符,第一列为数据表名,该表名后面的数据表是它的依赖表,生成的结果文件内容是
 *     第一列数据表的依赖表必须出现在该数据表的前面
 *   这是原始文件中的内容                    结果文件中的内容
 *      a b c                            c 
 *      b d e                            f 
 *      c                                d f 
 *      d f                            e c f 
 *      f                                b d e 
 *      e c f                            a b c 

 

package com.lineseque.main;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 功能:对文件每行的内容进行重排序,排序规则如下:
 * 	文件中的数据是以空格为分隔符,第一列为数据表名,该表名后面的数据表是它的依赖表,生成的结果文件内容是
 * 	第一列数据表的依赖表必须出现在该数据表的前面
 *   这是原始文件中的内容					结果文件中的内容
 * 	 a b c							c 
 * 	 b d e							f 
 * 	 c								d f 
 * 	 d f							e c f 
 * 	 f								b d e 
 * 	 e c f							a b c 
 * @author LinkTo
 *
 */
public class Sequence {
	// 缓存文件内容的变量,key 是文件中每行的第一列文本,value 是文件每一行除第一列外的其他文本信息
	private static Map<String, List<String>> lineCache = new HashMap<String, List<String>>();
	// 保存排好序的key索引,用来确定写入文件的顺序
	private static List<String> resTables = new LinkedList<String>();
	
	public static void main(String[] args) throws Exception {
		// 判断输入的参数个数是否为1,不是则退出
		if(args.length != 2) {
			System.err.println("args length not is 2, Please input args! $1 is input file, $2 is output file");
			return;
		}
		// 保存执行jar的输入参数:需要加载的文件路径名
		String inputFile = args[0];
		String outputFile = args[1];
		// 加载文件内容到lineCache变量中
		loadFile(inputFile);
		// 对lineCache中的表依赖关系进行排序
		dependSort();
		// 将结果写入到目标文件中
		outFile(outputFile);
		
	}
	// 将结果写入到目标文件中
	private static void outFile(String outputFile) throws Exception {
		// 声明缓存写入数据的变量
		StringBuffer str = new StringBuffer();
		// 声明写入文件的类
		FileWriter fw = new FileWriter(outputFile, false); //file是将要储存文件得地址,true/false是再次保存时是否覆盖上一次文件
		// 遍历resTables的内容,利用StringBuffer将resTables中的内容拼接成指定的格式
		for(String table : resTables) {
			str.append(table).append(" ");
			List<String> yilai = lineCache.get(table);
			for(String yltb : yilai) {
				str.append(yltb).append(" ");
			}
			str.append("\n");
		}
		// 写入文件中
		fw.write(str.toString());
		// 关闭流
		fw.close();
		
	}

	// 对lineCache中的表依赖关系进行排序
	private static void dependSort() {
		// 获取所有的表名,用来寻找lineCache缓存中的行信息
		List<String> tables = new LinkedList<String>(lineCache.keySet());
		// 保存排序后的结果内容,最后这里的内容将输出到结果文件中
		Map<String, List<String>> result = new HashMap<String, List<String>>();
		
		int index =0;
		// 循环遍历每一行,并判断和表有依赖关系的表是否出现在当前这张表的前面,是则保存到result中,并将key写入resTables
		while(!tables.isEmpty()) {
			// 当索引下标到达最后位置时,初始化index,重新下一边遍历
			if(index >= tables.size()) {
				index = 0;
			}
			// 获取下标为index的表名
			String table = tables.get(index);
			// 获取table的依赖
			List<String> yilai = lineCache.get(table);
			// 判断table是否有依赖表,如果没有则直接写入result中,进入下一次循环
			if(yilai.size() == 0) {
				result.put(table, new LinkedList<String>());
				tables.remove(index);
				resTables.add(table);
			}else { // 如果有,则遍历每一个依赖的表,查寻result中是否有对应的key,要所有的依赖表都可以在result中找到,才可以写入result中
				// 该变量用来判断依赖的表是否都存在result中
				int ylFlag = 0;
				// 遍历依赖的表
				for (String str : yilai) {
					// 如果依赖的表在result中不存在,则退出当前循环
					if(!result.containsKey(str)) {
						break;
					}
					ylFlag++;
				}
				// 判断ylFlag的值是否和yilai.size()的值相等,
				// 是则将该table表放入result中,否则进行下一次循环;
				// 在tables中清除table的记录,并在resTables中记录写入结果文件的顺序
				if(ylFlag == yilai.size()) {
					result.put(table, yilai);
					tables.remove(index);
					resTables.add(table);
				}else { // 如果两者不相等,则跳过当前这张table表,index下标加1,进入下一次循环
					index++;
				}
				
			}
			
		}
	}
	
	// 加载文件内容到lineCache变量中
	private static void loadFile(String filePath) throws Exception {
		
		InputStream is = new FileInputStream(new File(filePath));
		InputStreamReader isr = new InputStreamReader(is);// InputStreamReader 是字节流通向字符流的桥梁,
		BufferedReader br = new BufferedReader(isr);
		
		String buff = "";
		
		while((buff = br.readLine()) != null) {
			String[] words = buff.split(" ");
			
			if(words.length <= 1) {
				continue;
			}else if (words.length == 2) {
				lineCache.put(words[1], new LinkedList<String>());
				continue;
			}
			
			List<String> othersWord = new LinkedList<>();
			for(int c = 2; c < words.length; c++) {
				othersWord.add(words[c]);
			}
			lineCache.put(words[1], othersWord);
		
		}
		
		// 关流
		try {
			if(br != null) 
				br.close();
			if(isr != null) 
				isr.close();
			if(is != null) 
				is.close();
		} catch (Exception e) {
			if(br != null) 
				br.close();
			if(isr != null) 
				isr.close();
			if(is != null) 
				is.close();
		}finally {
			if(br != null) 
				br = null;
			if(isr != null) 
				isr = null;
			if(is != null) 
				is = null;
		}
		
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值