Map<String,MobileCard> cards = new HashMap<String,MobileCard>(); Map<String,List<ConsumInfo>> consumInfos = new HashMap<String,List<ConsumInfo>>();
一、前景提要
1.1 cards 对象
cards 中,值的类型为 MobileCard 实体类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * 嗖嗖移动卡 * @author ice_debj * */ @SuppressWarnings("serial") public class MobileCard implements Serializable{ private String cardNumber; // 卡号 private String userName; // 用户名 private String password; // 密码 transient private ServicePackage serpackage; // 所属套餐 private double price; private double consumAmount; // 当月消费金额 private double money; // 账户余额 private int realTalkTime; // 当月实际通话时长 private int realSMSCount; // 当月实际发送短信条数 private int realFlow; // 当月实际上网流量 // get、set方法集 public String getCardNumber() { return cardNumber; } public void setCardNumber(String cardNumber) { this.cardNumber = cardNumber; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public ServicePackage getSerpackage() { return serpackage; } public void setSerpackage(ServicePackage serpackage) { this.serpackage = serpackage; this.price = serpackage.getPrice(); } public double getConsumAmount() { return consumAmount; } public void setConsumAmount(double consumAmount) { this.consumAmount = consumAmount; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } public int getRealTalkTime() { return realTalkTime; } public void setRealTalkTime(int realTalkTime) { this.realTalkTime = realTalkTime; } public int getRealSMSCount() { return realSMSCount; } public void setRealSMSCount(int realSMSCount) { this.realSMSCount = realSMSCount; } public int getRealFlow() { return realFlow; } public void setRealFlow(int realFlow) { this.realFlow = realFlow; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } // 显示信息 public String showMeg() { return "MobileCard [cardNumber=" + cardNumber + ", consumAmount=" + consumAmount + ", money=" + money + ", password=" + password + ", realFlow=" + realFlow + ", realSMSCount=" + realSMSCount + ", realTalkTime=" + realTalkTime + ", userName=" + userName + "]"; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * 品牌套餐,父类 * @author ice_debj * */ public abstract class ServicePackage { private double price; // 套餐月资费 // get、set方法集 public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } // 显示套餐信息 public abstract String showInfo(); }
1.2 consumInfos 对象
consumInfos 中,值中所保存的为 ConsumInfo 对象的 List 集合框架
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * 消费信息 * @author ice_debj * */ @SuppressWarnings("serial") public class ConsumInfo implements Serializable{ private String cardNumber; // 卡号 private String type; // 消费类型 private double consumData; // 消费数据 public String getCardNumber() { return cardNumber; } public void setCardNumber(String ardNumber) { this.cardNumber = ardNumber; } public String getType() { return type; } public void setType(String type) { this.type = type; } public double getConsumData() { return consumData; } public void setConsumData(double consumData) { this.consumData = consumData; } }
二、存
2.1 cards 对象,存信息核心思想
a.txt 文本文件以行为分隔,保存手机号,即 cards 的键
a?.txt 文本文件以 0、1、2…… 为 a 的后缀,保存对应手机号的基本信息,以序列化对象形式保存于文件夹,即 cards 的值
注:MobileCard 为实体类,需要实现 Serializable 接口
MobileCard 成员变量中 serpackage 为 ServicePackage 类对象,在此不将其序列化
2.2 consumInfos 对象,存信息核心思想
b.txt 文本文件以行为分隔,一行保存手机号,一行保存上条手机号的消费记录条数,即 consumInfo 的键
?b?.txt 文本文件,以 0、1、2…… 为 b 的前缀,以 0、1、2……为 b 的后缀,即 consumInfo 的值
注:一个手机有多条记录信息,因此 b 的前缀为对应手机号的序号,b 的后缀为当前手机号的 n 条消费记录
ConsumInfo 为实体类,需要实现 Serializable 接口
2.3 实现代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 存,集合框架至文本文件 public void saveInfoToFile(){ // 获取要保存信息的两个主要文件对象 File file1 = new File("d:/ls/ls/a.txt"); File file2 = new File("d:/ls/ls/b.txt"); if(!file1.exists()){ try { file1.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } if(!file2.exists()){ try { file2.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } // cards 获取数据并添加到文本中 FileWriter fw = null; OutputStream fos = null; ObjectOutputStream oos = null; try { fw = new FileWriter(file1); int i=0; for(Map.Entry<String, MobileCard> ent: cards.entrySet()){ fw.write(ent.getKey()+"\n"); MobileCard mc = ent.getValue(); /* * 为避免代码过于混乱 * MobileCard 实体类中 ServicePackage serpackage 属性未序列化 * 将其成员变量保存至 price 成员变量中 */ mc.setPrice(mc.getSerpackage().getPrice()); fos = new FileOutputStream("d:/ls/ls/a"+i+".txt"); oos = new ObjectOutputStream(fos); oos.writeObject(mc); i++; } } catch (IOException e) { e.printStackTrace(); } finally { try { oos.close(); fos.close(); fw.close(); } catch (IOException e) { e.printStackTrace(); } } // consumInfos 获取数据并添加到文本中 try { fw = new FileWriter(file2); int j=0; for(Entry<String, List<ConsumInfo>> ent: consumInfos.entrySet()){ fw.write(ent.getKey()+"\n"); // 每条记录 ArrayList<ConsumInfo> list = new ArrayList<ConsumInfo>(); list = (ArrayList<ConsumInfo>) ent.getValue(); int i=0; for(;i<list.size();i++){ // 每条记录中,list 形式的消费记录 ConsumInfo ci = list.get(i); fos = new FileOutputStream("d:/ls/ls/"+j+"b"+i+".txt"); oos = new ObjectOutputStream(fos); oos.writeObject(ci); } fw.write(i+"\n"); oos.flush(); j++; } } catch (IOException e) { e.printStackTrace(); } finally { try { if(oos!=null){ oos.close(); } if(fos!=null){ fos.close(); } if(fw!=null){ fw.close(); } } catch (IOException e) { e.printStackTrace(); } } }
三、取
3.1 cards 对象,取信息核心思想
利用 BufferedReader 中 readLine() 方法读取数据,一行即即为一个手机号
在主循环中设置变量,用来获取保存 cards 对象中值的保存序列化对象的文件名
注:cards 对象中 serpackage 成员变量为 ServicePackage 类的对象,未被序列化,所以在此需要将其初始化
3.2 consumInfos 对象,取信息核心思想
主循环中外设置变量 int size=0,i=0,j=0; 分别对应:某条 map 键对应的,值保存的信息条数、读取行数、对应键的某个文本。
通过循环,奇数循环仅保存 consuminfos 键的值,偶数循环需要获取保存的键所对应值的条数。再通过循环获取序列化信息,保存至 list,循环结束后将其添加至 consumInfos 对象中。
注:在循环中,j:所指代的第几条键,因此需要在某条键的全部消费记录获取完成后,才仅需自增。
3.3 实现代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 取,文本文件至集合框架 public void initAddInfo(){ // 1、获取存放“键”文件的对象 File file1 = new File("d:/ls/ls/a.txt"); File file2 = new File("d:/ls/ls/b.txt"); File file = null; // 1.1、判断文件是否存在 if(!file1.exists()){ try { file1.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } if(!file2.exists()){ try { file2.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } // 2、cards 对象,获取数据,添加到集合框架中 FileReader fr = null; BufferedReader br = null; try { fr = new FileReader(file1); br = new BufferedReader(fr); String str = new String(""); int i=0; while((str=br.readLine())!=null){ // 循环得到每行信息,得到的即为一个账户 file = new File("d:/ls/ls/a"+i+".txt"); FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis); MobileCard mc = (MobileCard) ois.readObject(); /* * 存数据时,为避免代码过于混乱 * 实体类 MobileCard 中成员变量 ServicePackage serpackage 没有序列化 * 现根据保存的另一参数进行初始化。 */ ServicePackage serpackage = null; switch((int)mc.getPrice()){ case 68: serpackage = new NetPackage(); break; case 58: serpackage = new TalkPackage(); break; default: serpackage = new SuperPackage(); break; } mc.setSerpackage(serpackage); System.out.println(mc.showMeg()); cards.put(str, mc); i++; ois.close(); fis.close(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { try { br.close(); fr.close(); } catch (IOException e) { e.printStackTrace(); } } // consumInfos 获取文本数据并添加到集合框架中 try { fr = new FileReader(file2); br = new BufferedReader(fr); String str = new String(); int size = 0; // 获得某条 map 中list 保存条数 int i=0; //控制读取行数 String str2 = ""; // 保存键 int j=0; // 控制对应键的某个文本 while((str=br.readLine())!=null){ if(i%2==0){ // 读取键 str2 = str; }else{ List<ConsumInfo> list = new ArrayList<ConsumInfo>(); // 读取值 size = Integer.parseInt(str); for(;size>0;size--){ file = new File("d:/ls/ls/"+j+"b"+(size-1)+".txt"); FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis); list.add((ConsumInfo) ois.readObject()); } j++; consumInfos.put(str2, list); } i++; } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } }
四、总结
操作过于烦锁,此程序仅为帮助更好的理解 文件读入、写出机制。