1. JDK1. 7之后, 所有的流都实现了AutoCloseble接口,因此有了自动关闭流的心特性;
作业练习:使用Map集合;以及String 的split方法
"Success is the constant experience of failure and always keeping the initial enthusiasm"
把上列字符串以下列形式写入文件
Success=1
is=1
the=2
…..
1.构建出map集合 key存单词 value存单词出现的次数;
2.遍历map集合: 将数据写进去;
首先封装一个方法;
public static void fun( HashMap<String,Integer map, String string, File file> ){
//首先分割字符串;以空格为分割点;
String [] st = string.spalit(" ");
for( String key : st){
if(!map.containsKey(key)){
map.add(key,1)
}else{
Integer integer = map.get(key);
integer = integer+1;
map.add(key,integer);
}
}
//写文件
FileoutputStream f = new FileOutputStream(file);
//遍历map集合,首先边里map里面的key集合, 通过map.keySet()获取;
for(String stri:map.keySet){
Integer num = map.get(key);
f.write((key + "="+name+"\n").getBytes()); //这里写入必须是字符数组;
}
}
这时一个测试方法;
HashMap< String, Integer>map = new HashMap<>();
File file = new File("/Users/lanou/Desktop/text/zhang.txt");
String string = "Success is the constant experience of failure and always keeping the initial enthusiasm";
fun(map, file, string);
System.out.println(map);
2 . 使用字符缓冲流---BufferedWrite--BufferedReader--
注意: 1.使用字符缓冲读出来的字符串是不带换行的,需要手动进行换行;
2. 字符流必须flush(); 然后 close();
这里需要调用 缓冲流的特殊方法: newLine( ); 来实现换行;
2.1 :用Buffered进行读文件时候有个特有的方法, readLine() 一行一行读字符串;
下面封装一个读的方法:
FileRead fr = new FileRead("想要读的文件");
//创建一个缓冲流;
BufferedReader br = new BufferedReader(fr);
//定义一个字符串去接收读取的内容;
String str = "";
//结束的判断的条件是str=null;
while((str = br.read())!=null){
//想看就读完之后打印
System.out.println(string);
}
下面封装一个写的方法:
public static void fun(){
FileWriter fw = new FileWriter("给一个写的路径");
BufferedWriter bw = new BufferedWriter(fw);
//("这里可以直接写字符串")
bw.write("君不见");
//可以加上一个换行符;
bw.write("可怜 身上衣正单");
//字符流必须flush();
bw.flush();
bw.close();
}
3. Properties( 双列集合) 继承HashTable
集合中唯一一个能和 IO流产生关系的集合;
注意: properties.load( fileInputStream ) 从字节输入流中读取列表属性到集合:必须是有固定格式;
用处: 有些时候我们可以发送一个配置文件;不需要动代码,修改配置文件,就可以完成修改;
下面封装将文件里面内容读到集合里面;
private static void fun2properpties() throws FileNotFoundException, IOException {
//------1.创建properties数组 2.调用load( ---传入字节输入流-文件- )方法 3. 打印集合
//硬代码, 不修改代码,只是修改配置文件就行了;
// 读取文件方法;(load()加载)---最终 会把数据加载到集合中;
// key=value
Properties properties = new Properties();
// 文件名字规范,一把吧properties集合可以直接加载的文件的后缀名都使用propertier来表明
FileInputStream fileInputStream = new FileInputStream("/Users/lanou/Desktop/text/shuang.txt");
// 将数据加载到集合当中------需要穿入一个输入字节流
properties.load(fileInputStream);
// 关闭流资源
fileInputStream.close();
// ------打印集合默认调用toString方法----;
System.out.println(properties);
}
下面写一个将集合内容写到文件里 ( --properties . setProperty( String , String)--往集合里面填加独特的方法
注意; 用到 properties.store( fileOutputStream, 注释 ) ;注释可以不写,要写就写英文,中文乱码;
public static void write(){
properties p = new propertier();
p.setProperty("username","zhang");
p.setProerty("password","1234");
FileOutStream f=new FileOutputStrem("想要写入的路径文件");
p.store(f,"注释" )
}
4. 序列化与反序列化( 主要用于操作对象)
概述: 将对象写入文件中---- 和 -----将对象从文件中读取出来;
注意: 1. 如果成员变量是静态的, 该成员变量无法进行序列化;
2. 要使一个类可序列化; 必须实现Serializable接口:不实现会报出 :NotSerializableException
假如: 成员变量不写成静态的,也不想序列化,(transient ) 短暂的候鸟; 阻止成员变量序列化;
持久存储
我们经常需要将对象的字段值保存到磁盘中,并在以后检索此数据。 ( 对象一般是存放在内存中的,)
尽管不使用序列化也能完成这项工作,但这种方法通常很繁琐而且容易出错,
并且在需要跟踪对象的层次结构时,会变得越来越复杂。可以想象一下编写包含大量对象的大型业务应用程序的情形,
程序员不得不为每一个对象编写代码,以便将字段和属性保存至磁盘以及从磁盘还原这些字段和属性。
序列化提供了轻松实现这个目标的快捷方法。
什么叫序列化?
我们都知道对象是暂时保存在内存中的,不能用U盘考走了,有时为了使用介质转移对象,并且把对象的
状态保持下来,就需要把对象保存下来,这个过程就叫做序列化,通俗点,就是把人的魂(对象)收伏成一个石子(可传输的介质)
什么叫反序列化?
就是再把介质中的东西还原成对象,把石子还原成人的过程。
在进行这些操作的时候都需要这个可以被序列化,要能被序列化,就得给类头加[Serializable]特性。
通常网络程序为了传输安全才这么做。
写对象的方法;(-- writeObject( object )-----)
ublic static void write() throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("/Users/lanou/Desktop/text/wuqian.txt");
//创建序列化对象流
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
//Serializable 序列化接口 Serializable标识性接口,
//如果你这个类像进行序列化的话必须实现该接口; person类要实现该接口;
objectOutputStream.writeObject(new Person("蛮王", 18));
objectOutputStream.close();//必须记得关流
}
读对象的方法;(----readObject()----)
public static void read() throws IOException, ClassNotFoundException {
FileInputStream fileInputStream = new FileInputStream("/Users/lanou/Desktop/text/wuqian.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
// 读取独享依赖你的class文件来读取;
// 删除class测试
Object readObject = objectInputStream.readObject();
System.out.println(readObject);
objectInputStream.close();
5.练习键盘输入三个学生;
* 键盘录入6个学员信息(格式为 张三,男,25),要求有两个相同的信息
将6个学员信息存入到ArrayList集合中
将存有6个学员信息的ArrayList集合对象写入到文件中
读取文件中的ArrayList对象
对集合中的6个学生对象进行去重并按照年龄从小到大的顺序排序
再将排序完成的集合写进重新写进文件中
再重新读取 查看排序结果
*/
public class Demo06练习键盘录入 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//获取学生的数组,
//读和写
ArrayList<Student> list = fun();
//写入文件
writestudent(list);
//读一下
ArrayList<Student> readlist = read();
System.out.println(readlist);
//去重排序;
TreeSet<Student> st = new TreeSet<>();
//刷锅
st.addAll(readlist);
readlist.clear();
readlist.addAll(st);
//保存对象
writestudent(readlist);
//读一下
ArrayList<Student> readlist1 = read();
System.out.println(readlist1);
}
public static ArrayList<Student> fun() throws IOException {
ArrayList<Student> list = new ArrayList<>();
System.out.println("键盘录入6个学员信息(格式为 张三,男,25");
Scanner scanner = new Scanner(System.in);
while (list.size() < 3) {
// 接收用户信息;
String string = scanner.nextLine();
// 用逗号切割成数组;
String[] sp = string.split(",");
// 构建学生;
String name = sp[0];
String gender = sp[1];
int age = Integer.parseInt(sp[2]);
Student student = new Student(name, gender, age);
// 添加到数组中去;
list.add(student);
}
return list;
}
public static void writestudent(ArrayList<Student> list) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("/Users/lanou/Desktop/text/zhaomosheng.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
//直接把list集合写入文件
objectOutputStream.writeObject(list);
objectOutputStream.close();
}
public static ArrayList<Student> read() throws IOException, ClassNotFoundException {
FileInputStream fileInputStream = new FileInputStream("/Users/lanou/Desktop/text/zhaomosheng.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Object readObject = objectInputStream.readObject();
//强转成list 集合
ArrayList<Student> list = (ArrayList<Student>)readObject;
objectInputStream.close();
return list;
}
}
package lanou.com3g;
import java.io.Serializable;
public class Student implements Comparable<Student> ,Serializable{
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((gender == null) ? 0 : gender.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (gender == null) {
if (other.gender != null)
return false;
} else if (!gender.equals(other.gender))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", gender=" + gender + ", age=" + age + "]";
}
public Student(String name, String gender, int age) {
super();
this.name = name;
this.gender = gender;
this.age = age;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
private String name;
private String gender;
private int age;
@Override
public int compareTo(Student o) {
int num = o.getAge()-this.getAge();
return num;
}
}
注意: 去重: 需要重写equals方法; 和hascode方法:
排序: 自己创建的类,需要实现comparable接口: 重写comparable方法;