1.Title
用Java语言实现通讯录管理系统
2.Requests
- 设计一个能够记录学生通讯录的数据结构(比如包括:学号,姓名,年龄,性别,联系电话,住址等)。
- 应用文件(或数据库)保存通讯录数据。
- 新增:能将所有输入的通讯录数据保存到文件中,并可选择继续输入或退出。
- 查找:输入学生的学号,并在文件中查找,若找到,则显示该学生详情,否则提示未找到。
- 删除:输入学生的学号,并在文件中查找;若找到,提示是否确定删除;若选择是,则删除文件中该学生信息;若选择否,则取消,否则提示无此学生信息
- 修改:输入学生的学号,并在文件中查找;若找到,显示学生的所有信息,并可进行输入。完成后将现输入的内容覆盖原内容保存到文件中。否则提示无此学生信息。
- 退出:退出程序
3.Readme
- 不要自己创建用来存储数据的txt文件,代码会自动创建,代码运行后要添加一个人员信息(只要添加过一个人员信息就行,添加后接着删除了也可以,因为添加第一个人员信息之后会创建文件头部格式,删除人员信息的时候不会删除文件头部格式),不然第二次运行的时候会出现一个空的文本文档,而这个空的文档与文档插入数据的格式不匹配,会导致运行失败,此时应当删除空的文档,重新运行代码,让代码帮你新建一个文件。注意:虽然自己创建在本地的储存数据的文件是txt格式的,但是ObjectOutputStream处理输出输出的内容不是文本格式,如果用记事本打开会是乱码。解释摘抄如下:
- 1.ObjectOutputStream 对Java对象进行序列号处理,处理后的数据,不是文本数据,
所以,该数据虽然是保存到文件中,用文本编辑器打开,必乱码。
2.输出流,在写入之后,一般都会调用flush方法,将缓冲区的数据刷到IO中去
(当然,楼主的目的地是硬盘文件中)。IO读写,一般情况下,操作系统也会建立一定大小的缓冲区。
3.输出流,在所有写入操作都做完后,应该关闭IO流,调用close方法。
除了可以回收系统资源外,也会强制刷新系统缓冲区中的数据至硬盘。
4.object_in引用对应的是输入流对象,流是流动的,当你上面写入一个对象到文件中后,
下面就只能从那个文件中读取一个对象,再调用读取方法,什么也读不到。
所以,System.out.println(object_in.readObject());的参数应该是li。
5.输入流在读取完成后,也要进行关闭,回收系统资源。
最后,回答楼主说的乱码问题,我上面已经说明了,
楼主应该仔细理解Java对象的序列话操作到底干了什么。
它不是简单的把对象属性值写入IO流中,而是按照一定的数据格式写入的。
而这种格式,不是记事本、写字板、Word等文本编辑器能够识别的,
因为,这些数据,压根就不是文本数据。
只有使用相同版本的Java的ObjectInputStream来进行读取操作。
并且,流数据,在没有缓冲区的情况下,是不能读取重复数据的。
也就是说,如果,我的文本文件中,存放12345这五个字符,
那么,我用流读取一个字符,第一个是字符1,第二次读取,必然是字符2,
不可能还是字符1,除非你用带缓冲区缓的流对象,这样,你在读取前先做标记,
读取完了,可以回退到标记处,重复读取数据,
当然,数据的当前位置和标记位置之间的距离不能超过缓冲区的大小。
4.Code
package top.oneluckyguy.pro;
/**
* @author Liu Qingfeng
* @create 2020-12-18----15:57
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Student implements Serializable{
private static final long serialVersionUID = 1L;
private String number;//学号
private String name;//姓名
private String age;//年龄
private String sex;//性别
private String phone;//手机号码
private String address;//地址
private String email;//邮箱
static final String Files="d:/addressBook.txt";//文件存放的路径
static Scanner input=new Scanner(System.in);//创建静态输入流对象
List<Student> listStudent=new ArrayList<Student>();
static File f=null;
public static void main(String[] args) throws IOException, ClassNotFoundException {
Student a=new Student();
f = new File(Files);//将一个字符串描述的路径,封装成一个File对象。
if(!f.exists())//判断文件是否存在
{
f.createNewFile();//不存在则创建一个文件
}
else
{
a.readStduent();//存在的话就通过反序列化读取数据
}
int n=1;//作为循环条件(1相当于true)
String m;
while(n!=0)
{
menu();
System.out.println("请输入想要进行的操作:");
m=input.next();
switch(m)
{
case "1":
a.add();
break;
case "2":
a.remove();
break;
case "3":
a.modify();
break;
case "4":
a.find();
break;
case "5":
a.show();
break;
case "6":
n=0;
break;
default:
System.out.println("输入无效请重新输入");
}
}
System.out.println("程序退出成功!!");
}
//有参构造函数
public Student(String number,String name,String age,String sex,String phone,String address,String email)
{
this.number=number;
this.name=name;
this.age=age;
this.sex=sex;
this.phone=phone;
this.address=address;
this.email=email;
}
//无参构造函数
public Student()
{
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
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 getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
//重写toString方法
public String toString() {
return "[学号:" + number + ", 姓名:" + name + ", 年龄:" + age +", 性别:" + sex +", 手机号码:" + phone + ", 地址:" + address + ", 邮箱"
+ email + "]";
}
/*
* 通过反序列化从文件里面获取数据
*/
void readStduent() throws FileNotFoundException, IOException, ClassNotFoundException
{
ObjectInputStream ins;
ins=new ObjectInputStream(new FileInputStream(Files));
listStudent = (List<Student>) ins.readObject();
ins.close();
}
/*
* 实现增删改操作的方法
*/
//添加方法
void add()
{
System.out.println("请分别输入 学号,姓名,年龄,性别,手机号,地址,邮箱(每条信息以回车分割)");
String number=input.next();
String name=input.next();
String age=input.next();
String sex=input.next();
String phone=input.next();
String address=input.next();
String email=input.next();
int flag1 = 1;
Student s1=new Student(number,name,age,sex,phone,address,email);
ObjectOutputStream out = null;
for (Student s:listStudent){
if (s.getNumber().equals(number)){
flag1 = 0;
}
}
if(flag1 == 0){
System.out.println("添加信息失败,已有此学号的学生的信息");
}else{
try {
System.out.println("");
listStudent.add(s1);
System.out.println(s1 +"已存储到本地");
out=new ObjectOutputStream(new FileOutputStream(Files));
out.writeObject(listStudent);
} catch (IOException e) {
e.printStackTrace();
}finally
{
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("如果相继续输入学生数据请输入1,输入其他字符返回上一级");
String flag=input.next();
if(flag.equals("1")){
add();
}
}
}
//删除方法(通过学号删除)
void remove()
{
int flag3 = 0;
System.out.println("请输入想要删除的学生信息的学号:");
String number=input.next();
for(Student s:listStudent)
{
if(s.getNumber().equals(number))
{
System.out.println("是否真的要删除y/n?");
checkDelete(s);
return;
}
}
System.out.println("删除失败,没有找到此人!!");
}
void checkDelete(Student s){
String flag = input.next();
if ("y".equals(flag)){
ObjectOutputStream out1 = null;
listStudent.remove(s);
System.out.println("删除成功!");
try {
out1=new ObjectOutputStream(new FileOutputStream(Files));
out1.writeObject(listStudent);
} catch (IOException e) {
e.printStackTrace();
}finally
{
try {
out1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}else if ("n".equals(flag)){
System.out.println("取消删除成功");
}else{
System.out.println("输入不合法,请输入y或者n");
checkDelete(s);
}
}
//通过学号修改个人信息
void modify()
{
System.out.println("请输入想要修改的个人信息的学号:");
String number=input.next();
int flag = 1;
ObjectOutputStream out2 = null;
for(Student s:listStudent)
{
if(s.getNumber().equals(number))
{
System.out.println(s);
flag = 0;
}
}
if (flag == 1){
System.out.println("修改失败,没有此学生信息");
}else{
for(Student s:listStudent)
{
if(number.equals(s.getNumber()))
{
System.out.println("请依次输入修改之后的: 学号,姓名,年龄,性别,手机号码,地址,邮箱");
String number1=input.next();
String name1=input.next();
String age1=input.next();
String sex1=input.next();
String phone1=input.next();
String address1=input.next();
String email1=input.next();
int flag2 = 1;
for (Student st:listStudent){
if (st.getNumber().equals(number1)&& !number.equals(number1)){
flag2 = 0;
}
}
if(flag2 == 0){
System.out.println("修改信息失败,已有此学号的学生的信息");
}else{
System.out.println("修改学生信息成功");
s.setNumber(number1);
s.setName(name1);
s.setAge(age1);
s.setSex(sex1);
s.setPhone(phone1);
s.setAddress(address1);
s.setEmail(email1);
try {
out2=new ObjectOutputStream(new FileOutputStream(Files));
out2.writeObject(listStudent);
} catch (IOException e) {
e.printStackTrace();
}finally
{
try {
out2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
}
//显示所有人信息
void show(){
if (listStudent.isEmpty()){
System.out.println("您的个人通讯录为空");
}
for(Student s:listStudent)
{
System.out.println(s);
}
}
//查找(通过姓名或地址)
void find()
{
System.out.println("请输入学号:");
String number=input.next();
for(Student s:listStudent)
{
if(s.getNumber().equals(number))
{
System.out.println(s);
return;
}
}
System.out.println("查无此人!!");
}
//菜单方法
static void menu()
{
System.out.println("*******************************************************");
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("〓〓〓〓〓〓〓〓 * 6、exit * 〓〓〓〓〓〓〓〓");
}
}