A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 赵玮_Tom 中级黑马   /  2012-5-3 19:34  /  4186 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

看过基础视频的应该都记得那个“限制软件试用期限”的小程序。程序是这样的:
import java.io.*;
import java.util.*;
class Test
{
public static void main(String args [])
{
  try
  {
   getRunCount();
  }
  catch (IOException e)
  {
   throw new RuntimeException("程序出现异常");
  }
}
public static void getRunCount() throws IOException
{
  Properties prop = new Properties();
  File propFile = new File("times.ini");
  if(!propFile.exists())
   propFile.createNewFile();
  
  FileInputStream fis = new FileInputStream(propFile);
  
  
  prop.load(fis);
  
  String value = prop.getProperty("time");
  int count = 0;
  if(value!=null)
   count=Integer.parseInt(value);
  if(count>=5)
  {
   System.out.println("使用日期已到,给钱!");
   return;
  }
  count++;
  
  prop.setProperty("time", count+"");
  
  FileOutputStream fos = new FileOutputStream(propFile);
  prop.store(fos, "list");
  
  fis.close();
  fos.close();
}
}

然而,当后来复习时,自己写过这个程序,代码如下:
import java.io.*;
import java.util.*;
class Test151
{
public static void main(String args [])
{
  try
  {
   getRunCount();
  }
  catch (IOException e)
  {
   throw new RuntimeException("程序出现异常");
  }
}
public static void getRunCount() throws IOException
{
  Properties prop = new Properties();
  File propFile = new File("info.ini");
  if(!propFile.exists())
   propFile.createNewFile();
  
  FileInputStream fis = new FileInputStream(propFile);
  FileOutputStream fos = new FileOutputStream(propFile);
  
  prop.load(fis);
  
  String value = prop.getProperty("time");
  int count = 0;
  if(value!=null)
   count=Integer.parseInt(value);
  if(count>=5)
  {
   System.out.println("试用期限已到,否则电脑炸掉!");
   return;
  }
  count++;
  
  prop.setProperty("time", count+"");
  
  
  prop.store(fos, "list");
  
  fis.close();
  fos.close();
}
}

仔细观察代码,只有一处不同,就是输出流定义的位置不同。但就是这一处不同导致上面的程序运行正常,而下面的程序代码
无法正常运行,文件中time的值始终为1。不知为什么,请教。

11 个回复

倒序浏览
看了半天,每次运行时value的值都是null,
也就是prop.load(fis);这句话好像一直没执行成功,
没有把FileInputStream的加载文件加在到prop中去。
只要把fos=new FileOutputStream(file);放在prop.load(fis);之后就可以了,
为什么要这样放也没明白,等高手,顶下,别沉了。
回复 使用道具 举报
第二段程序改为:FileOutputStream fos = new FileOutputStream(propFile,true);
以追加方式创建FileOutputStream
原因是每次执行FileOutputStream fos = new FileOutputStream(propFile);都会把原来的内容清空,这样value永远得到null,count永远为1。
第一段程序是读完文件后才执行FileOutputStream fos = new FileOutputStream(propFile);清空了数据也没事。
回复 使用道具 举报
2楼v5,我也学到了,嘿嘿,
回复 使用道具 举报
根本原因 FileOutputStream fos = new FileOutputStream(propFile);
这个构造方法是重载的,查看api 你会发现直接 new FileOutputStream(propFile) 默认为覆盖重写,所以你new 的时候文件已经为空了,
那么如果你不想改变程序代码的位置,则可以继续看api 使用 new FileOutputStream(propFile, arg1), 只要把arg1设置为true 则可以了,表示append 即添加到文件末尾,这样则不会覆盖原来的文件了。
但是呢? 这是添加,文件中会出现大量的重复信息(程序是正确的,能达到目标效果),而我们需要的是覆盖源文件,说回来,最好还是以覆盖形式写在prop.load(fis)后面的好!
回复 使用道具 举报
谢谢大家,终于明白了
回复 使用道具 举报
赵同学看起来好面熟
回复 使用道具 举报
徐慧书 发表于 2012-5-3 20:31
根本原因 FileOutputStream fos = new FileOutputStream(propFile);
这个构造方法是重载的,查看api 你会发 ...

谢谢,已经基本明白了。只是有一点我还不懂,如果以续写的方式创建写入流,文件中出现大量重复信息,也就是说会出现多个time=XX的键值对,当再一次执行prop.load(fis)时,会加载那个time=Xx的信息呢?(已验证程序确实可以执行,只是不明白为什么会加载最后一个time=XX的属性信息。
回复 使用道具 举报
赵玮_Tom 发表于 2012-5-3 21:38
谢谢,已经基本明白了。只是有一点我还不懂,如果以续写的方式创建写入流,文件中出现大量重复信息,也就 ...

对于这点可以这样理解,这里面的实现是使用HashMap,这个map应该使用过吧,当我们对同一个key:time重复add(key,value)后key所对应的值是哪个呢? 自然保留的是最后一个。
同理当文件中出现多个time=1,time=0 。。。  等等 时,就是在不断重复的过程,前面的值全部都被覆盖掉了,保留的永远都是最后一个!哦了
回复 使用道具 举报
徐慧书 发表于 2012-5-4 09:34
对于这点可以这样理解,这里面的实现是使用HashMap,这个map应该使用过吧,当我们对同一个key:time重复a ...

thanks      
回复 使用道具 举报
攒分升级用户组
回复 使用道具 举报
楼主,可以加QQ吗?现在也要写这个功能,能讨论下吗?917425916这是我的QQ
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马