- ArrayList集合类保存数据只是在内存中暂时存储,不能永久的存储,这样会导致数据的丢失。
- Java对数据的操作是通过流的方式,这些操作流的类都在IO包中,所以需要导包。IO流就是用来处理设备之间的数据传输,可以把数据存储到文件,也可以从文件中读取出来。
- 可以把自己理解成Java程序,当把数据存储到文件时,是java程序把程序中的数据写进文件中,需要输出流;当从文件中读数据时,是Java程序需要在文件中读取数据到Java程序,需要输入流。
FileWriter类
- 构造方法:FileWriter(String fileName)传入一个文件的路径
- 成员方法:
- void write(String str)向文件中写一个字符串str数据
- void write(String str,int index,int len)写入一个以index开始,长度为len的字符串的一部分数据
- void write(int ch)写入一个字符数据,可以是char类型的数据,也可以是char类型对应的int类型的值,所以写的是int类型。
- void write(char[] chs)写一个字符数组
- void write(char[] chs,int index, int len)写一个以index开始,长度为len的字符数组的一部分数据
- void flush()将内存中的数据刷新到文件中
- void close()释放资源
public static void main(String[] args) throws IOException {
FileWriter fw =new FileWriter("d:\\a.txt");
//输出流的写方法
fw.write("hello,world.");
fw.write("\r\n");
//硬盘存储数据的最基本的单位是字节,而我们存的是字符串,没有直接写到文件,而是写到了内存缓冲区,需要刷新,把数据放进去。
fw.flush();
fw.write("abcdef", 1, 3);
fw.write("\r\n");
fw.flush();
fw.write(97);
fw.write('a');
fw.write("\r\n");
fw.flush();
char[] chs ={'h','e','l','l','o'};
fw.write(chs);
fw.write("\r\n");
fw.flush();
fw.write(chs, 1, 2);
fw.write("\r\n");
fw.flush();
fw.close();
}
a.txt中的结果:
hello,world.
bcd
aa
hello
el
注意:
- 绝对路径:以盘符开始的路径。(d:\a.txt),
相对路径:直接写文件名就好,想对于当前项目而言,在项目的根目录下(a.txt)。 - windows系统中自带的记事本换行是 \r\n。
- close()和flush()方法的区别:
flush:刷新缓冲区,流对象还可以继续使用。
close:先刷新缓冲区,然后通知系统释放资源,流对象不可以再被使用了,最后必须释放资源,否则会出现一些因为类似程序没有执行完,删除文件无法删除的现象。 - 实现数据的追加: FileWriter fw =new FileWriter(“d:\a.txt”,true);
使用的构造方法:FileWriter(String fileName,boolean append);
FileReader类
- 构造方法:FileReader(String fileName):传递文件名称
- 成员方法:
- int read():一次读取一个字符
- int read(chs):一次读取一个字符数组的数据
public static void main(String[] args) throws IOException {
FileReader fr =new FileReader("d:\\a.txt");
/*//一次读取一个字符
int ch;
while((ch=fr.read())!=-1){
System.out.print((char)ch);
}*/
char[] chs =new char[1024];
int len;
while((len=fr.read(chs))!=-1){
//将字符数组中从0开始的长度为len的数据转换成字符串
System.out.println(new String(chs,0,len));
}
fr.close();
}
注意:
- 注释中是第一种,一次读取一个字符,读取数据的返回值是-1,就说明没有数据了,读取的字符是int型的,需要转换成char型,不需要加换行,文件中的换行,可以读到。
- 第二种是一次读取一个字符数组的数据,返回的是实际读取的个数,字符容量一般可以是1024或1024的整数倍。
缓冲流类
- BufferedWriter将文本写入字符输出流,缓存各个字符,从而提供单个字符、数组和字符串的高效写入。
构造方法:BufferedWriter(Writer out)
缓冲流的特殊功能:void newLine()写一个换行符,这个换行符由系统决定,不同的操作系统,该方法使用的换行符不同。
其他方法和基本流的方法一样。 - BufferedReader从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
特殊方法:String readLine()一次读取一行数据,不读取换行符。读出来的一行为null时,读取结束。
复制文件的例子:
public static void main(String[] args) throws IOException {
BufferedReader br=new BufferedReader(new FileReader("d:\\a.txt"));
BufferedWriter bw =new BufferedWriter(new FileWriter("b.txt"));
String line;
while((line =br.readLine())!=null){
bw.write(line);
bw.newLine();//相当于bw.write("\r\n");
bw.flush();
}
bw.close();
br.close();
}
一般都使用的缓冲流,可以实现和集合中的数据的写入和读取。
Java使用集合类和IO流实现学生管理系统的案例。
Student类的代码:
public class Student {
private String id;//学号
private String name;//姓名
private String age;//年龄
private String address;//地址
public Student() {
}
public Student(String id, String name, String age, String address) {
this.id = id;
this.name = name;
this.age = age;
this.address = address;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
test类中的代码:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
public class StudentDemo {
public static void main(String[] args) throws IOException {
String fileName = "Student.txt";
//创建集合对象,用于存储学生数据
//ArrayList<Student> array = new ArrayList<>();
//为了让程序可以回到这来,重新选择别的选项,使用循环
while(true){
System.out.println("--------欢迎来到学生管理系统-------");
System.out.println("1 查看学生所有信息");
System.out.println("2 添加学生");
System.out.println("3 删除学生");
System.out.println("4 修改学生");
System.out.println("5 退出");
System.out.println("请输入你的选择:");
Scanner sc = new Scanner(System.in);
String choice = sc.nextLine();
switch(choice){
case"1":
findAllStudent(fileName);
//findAllStudent(array);
break;
case"2":
addStudent(fileName);
//addStudent(array);
break;
case"3":
deleteStudent(fileName);
//deleteStudent(array);
break;
case"4":
updateStudent(fileName);
//updateStudent(array);
break;
case"5":
//case穿透,不需要写下面这两行
/*System.out.println("谢谢你的使用");
break;*/
default:
System.out.println("谢谢你的使用");
//系统退出,JVM退出
System.exit(0);
break;
}
}
}
//将集合中的数据写到文件中
public static void writeData(String fileName,ArrayList<Student> array) throws IOException{
BufferedWriter bw = new BufferedWriter(new FileWriter(fileName));
for(int i=0;i<array.size();i++){
Student s =array.get(i);
StringBuilder sb =new StringBuilder();
sb.append(s.getId()).append(",").append(s.getName())
.append(",").append(s.getAge()).append(",").append(s.getAddress());
bw.write(sb.toString());
bw.newLine();//换行
bw.flush();
}
bw.close();
}
//将文件读入到集合中
public static void readData(String fileName,ArrayList<Student> array) throws IOException{
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line;
while((line=br.readLine())!=null){
String[] str =line.split(",");
Student s =new Student();
s.setId(str[0]);
s.setName(str[1]);
s.setAge(str[2]);
s.setAddress(str[3]);
array.add(s);
}
br.close();
}
//修改学生
private static void updateStudent(String fileName) throws IOException {
//读入数据到集合中
ArrayList<Student> array = new ArrayList<>();
readData(fileName, array);
Scanner sc= new Scanner(System.in);
System.out.println("请输入要修改的学生学号:");
String id = sc.nextLine();
int index=-1;
for(int i=0;i<array.size();i++){
Student s =array.get(i);
if(s.getId().equals(id)){
index =i;
break;
}
}
if(index==-1){
System.out.println("不好意思,你要修改的学号对应的学生不存在");
}else{
System.out.println("请输入学生新姓名:");
String name = sc.nextLine();
System.out.println("请输入学生新年龄:");
String age = sc.nextLine();
System.out.println("请输入学生新居住地:");
String address = sc.nextLine();
//创建学生对象
Student s = new Student();
s.setId(id);
s.setName(name);
s.setAge(age);
s.setAddress(address);
array.set(index, s);
//写到文件中
writeData(fileName, array);
System.out.println("修改学生成功");
}
}
//删除学生
private static void deleteStudent(String fileName) throws IOException {
//读入数据到集合中
ArrayList<Student> array = new ArrayList<>();
readData(fileName, array);
Scanner sc= new Scanner(System.in);
System.out.println("请输入要删除的学生学号:");
String id = sc.nextLine();
int index=-1;
for(int i=0;i<array.size();i++){
Student s =array.get(i);
if(s.getId().equals(id)){
index =i;
break;
}
}
if(index==-1){
System.out.println("不好意思,你删除的学号对应的学生不存在");
}else{
array.remove(index);
writeData(fileName, array);
System.out.println("删除学生成功");
}
}
//添加学生
private static void addStudent(String fileName) throws IOException {
//读入数据到集合中
ArrayList<Student> array = new ArrayList<>();
readData(fileName, array);
Scanner sc= new Scanner(System.in);
String id;
while(true){
System.out.println("请输入学生学号:");
id = sc.nextLine();
boolean flag =false;
for(int i=0;i<array.size();i++){
Student s =array.get(i);
if(s.getId().equals(id)){
flag = true;
break;
}
}
if(flag==true){
System.out.println("输入的学号已经被占用,请重新输入:");
}else{
break;
}
}
System.out.println("请输入学生姓名:");
String name = sc.nextLine();
System.out.println("请输入学生年龄:");
String age = sc.nextLine();
System.out.println("请输入学生居住地:");
String address = sc.nextLine();
//创建学生对象
Student s = new Student();
s.setId(id);
s.setName(name);
s.setAge(age);
s.setAddress(address);
//把学生对象作为元素添加到集合
array.add(s);
//写到文件中
writeData(fileName, array);
//给出提示
System.out.println("添加学生成功");
}
//查询学生列表
private static void findAllStudent(String fileName) throws IOException {
//读入数据到集合中
ArrayList<Student> array = new ArrayList<>();
readData(fileName, array);
if(array.size()==0){
System.out.println("不好意思,目前没有学生信息可供查询,请重新选择:");
return;
}
System.out.println("学号\t姓名\t年龄\t住址");
for(int i=0;i<array.size();i++){
Student s = array.get(i);
System.out.println(s.getId()+"\t"+s.getName()+"\t"+s.getAge()+"\t"+s.getAddress());
}
}
}
这个案例中没有加入任何的框架,单纯学Java基础的时候使用集合类和IO缓冲流实现的一个小案例,中间也加入StringBuilder的使用以及StringBuilder和String的转换。