IO流操作文件相关方法(二)
3.万能输出流打印流
- PrintWriter PrintStream
- 特点:
只能写数据,不能读取数据。
可以操作任意类型的数据。
如果启动了自动刷新,能够自动刷新。
如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作
例题:
模拟记录用户登录日志(采用追加方式记录),
从控制台接收用户输入的用户名和密码,在文件中记录用户名和密码以及登录时间。
格式如下:
name=zhangsan
pwd=123456
时间=2014-06-05 18:22:33
public static void main(String[] args) throws IOException {
Scanner input = new Scanner(System.in);
System.out.println("请输入用户名:");
String userName = input.next();
System.out.println("请输入密码:");
String password = input.next();
System.out.println("是否登录?(Y/N)");
String yesOrNo = input.next();
if ("Y".equals(yesOrNo)) {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String dateStr = sdf.format(date);
PrintWriter pw = new PrintWriter(new FileWriter("userInfo.txt"), true);
pw.println("name=" + userName);
pw.println("pwd=" + password);
pw.print("时间=" + dateStr);
pw.close();
System.out.println("登录成功");
} else {
System.out.println("登录失败");
}
}
4.随机访问文件
- RandomAccessFile;
- 概述:此类的实例支持对随机访问文件的读取和写入。
- 特点
RandomAccessFile类不属于流,是Object类的子类。
包含了InputStream和OutputStream的功能。
支持对随机访问文件的读取和写入:
RandomAccessFile(String name, String mode)
getFilePointer: 获取文件指针
seek: 设置文件指针
public static void main(String[] args) throws Exception {
// write();
read();
}
public static void read() throws Exception {
// 当成读的流处理
RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
raf.seek(5);
// byte b = raf.readByte();
// int i = raf.readInt();
byte[] bys = new byte[8];
int len = raf.read(bys);
// System.out.println(b);
// System.out.println(i);
System.out.println(new String(bys, 0, len));
raf.close();
}
public static void write() throws IOException {
// 当成写的流处理
RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");
raf.writeByte(20);
raf.writeInt(10);
long fp = raf.getFilePointer();
System.out.println(fp);
raf.write("中国你好".getBytes());
fp = raf.getFilePointer();
System.out.println(fp);
raf.close();
}
5.序列化流与反序列化流
-
ObjectOutputStream / ObjectInputStream
ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。 -
如何实现序列化?
类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化,该接口没有任何方法,是一个标机接口。
未实现序列化抛出未序列化异常:NotSerializableException。 -
序列化数据后,再次修改类文件,读取数据会出问题,如何处理?
使用transient关键字声明不需要序列化的成员变量。 -
java.io.NotSerializableException
异常名称: 没有序列化异常
产生原因: 在将对象保存到文件系统的时候没有将对象实现序列化接口
解决方法: 针对需要写入到文件系统的对象实现对应的序列化接口Exception in thread “main” java.io.InvalidClassException:
com.sxt.otherio.Person; local class incompatible:
stream classdesc serialVersionUID = -6469125083721773098,
local class serialVersionUID = 4687267829016438016 -
InvalidClassException: 无效类异常
产生原因: 文件中保存的流的序列化id和本地类文件的序列化id不匹配
解决办法: 保证id一致性 -
transient: 在将成员写入到文件的时候确保数据的安全,在反序列化的时候不能够获取到数据
public static void main(String[] args) throws Exception {
// write();
read();
}
public static void read() throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));
Object obj = ois.readObject();
System.out.println(obj);
ois.close();
}
public static void write() throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));
Object obj = new Person("隔壁老王", 40);
oos.writeObject(obj);
oos.close();
}
}
class Person implements Serializable{
private static final long serialVersionUID = -3911255650485738676L;
private String name;
private transient int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
6.Properties属性集
- 当做属性集来使用
- Properties的特殊遍历功能
public Object setProperty(String key,String value)
public String getProperty(String key)
public Set stringPropertyNames() - Properties和IO流结合使用
public void load(Reader reader)
public void store(Writer writer,String comments) - 例题
已知文本文件(userinfo.txt)如下图所示,数据是键值对形式的,
请写一个程序判断是否有admin这样的用户存在,如果有就改变密码为“56789”。
public static void main(String[] args) throws Exception, IOException {
Properties properties = new Properties();
properties.load(new FileReader("userInfo.txt"));
Set<String> keys = properties.stringPropertyNames();
for (String key : keys) {
if (key.equals("admin")) {
properties.setProperty("admin", "56789");
}
}
properties.store(new FileWriter("userInfo.txt"), null);
}
上一篇: php中for while循环语句学习笔记_PHP教程
下一篇: io流