前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >第二十三天 IO-打印流&序列化流&Properties&CommonsIO&流总结【悟空教程】

第二十三天 IO-打印流&序列化流&Properties&CommonsIO&流总结【悟空教程】

作者头像
Java帮帮
发布2018-07-26 15:47:02
5310
发布2018-07-26 15:47:02
举报

第二十三天 IO-打印流&序列化流&Properties&CommonsIO&流总结【悟空教程】

第23天 IO

第1章 流的复习总结

第2章 打印流

2.1 打印流的概述

打印流添加输出数据的功能,使它们能够方便地打印各种数据值表示形式.

打印流根据流的分类:

  • 字节打印流 PrintStream
  • 字符打印流 PrintWriter
  • 方法:

void print(String str): 输出任意类型的数据,

void println(String str): 输出任意类型的数据,自动写入换行操作

/*

* 需求:把指定的数据,写入到printFile.txt文件中

*

* 分析:

* 1,创建流

* 2,写数据

* 3,关闭流

*/

public class PrintWriterDemo {

public static void main(String[] args) throws IOException {

//创建流

//PrintWriter out = new PrintWriter(new FileWriter("printFile.txt"));

PrintWriter out = new PrintWriter("printFile.txt");

//2,写数据

for (int i=0; i<5; i++) {

out.println("helloWorld");

}

//3,关闭流

out.close();

}

}

2.2 打印流完成数据自动刷新

可以通过构造方法,完成文件数据的自动刷新功能,自动刷新适用部分方法,如println方法,平常使用的write方法不提供自动刷新

  • 构造方法:
    • 开启文件自动刷新写入功能

public PrintWriter(OutputStream out, boolean autoFlush)

public PrintWriter(Writer out, boolean autoFlush)

/*

* 分析:

* 1,创建流

* 2,写数据

*/

public class PrintWriterDemo2 {

public static void main(String[] args) throws IOException {

//创建流

PrintWriter out = new PrintWriter(new FileWriter("printFile.txt"), true);

//2,写数据

for (int i=0; i<5; i++) {

out.println("helloWorld");

}

//3,关闭流

out.close();

}

}

第3章 序列化流

3.1 序列化流概念

序列化流可以将对象进行序列化和反序列化。

用于从流中读取对象的操作流 ObjectInputStream称为反序列化流

用于向流中写入对象的操作流 ObjectOutputStream称为序列化流

注意:对象序列化时,对象的数据类型定义时一定要实现Serializable接口,从而实现可持久化。

3.2 序列化流

将一个对象以对象的形式存储到文件中。

ObjectOutputStream writeObject() 写出对象

public class ObjectStreamDemo {

public static void main(String[] args) throws IOException, ClassNotFoundException {

/*

* 将一个对象存储到持久化(硬盘)的设备上。

*/

writeObj();//对象的序列化。

}

public static void writeObj() throws IOException {

//1,明确存储对象的文件。

FileOutputStream fos = new FileOutputStream("aa\\obj.txt");

//2,给操作文件对象加入写入对象功能。

ObjectOutputStream oos = new ObjectOutputStream(fos);

//3,调用了写入对象的方法。

oos.writeObject(new Person("wangcai",20));

//关闭资源。

oos.close();

}

}

3.3 对象反序列化流

当把一个对象持久化存储起来之后,需要使用反序列化技术获取存储起来的对象

ObjectInputStream readObject() 读取对象

使用此ObjectInputStream对象就可以完成反序列化动作

public class ObjectStreamDemo {

public static void main(String[] args) throws IOException, ClassNotFoundException {

readObj();//对象的反序列化。

}

public static void readObj() throws IOException, ClassNotFoundException {

//1,定义流对象关联存储了对象文件。

FileInputStream fis = new FileInputStream("aa\\obj.txt");

//2,建立用于读取对象的功能对象。

ObjectInputStream ois = new ObjectInputStream(fis);

Person obj = (Person)ois.readObject();

System.out.println(obj.toString());

}

}

3.4 将用户信息存储到文件中与读取文件用户

3.4.1 用户实体类

import java.io.Serializable;

/*

*

* Serializable 接口

* 作用: 想要序列化,就必须实现这个 接口. 不用重写任何方法. 只是标记 一下.

*/

public class User implements Serializable{

String name ;

String psw ;

int age;

public User() {

super();

}

public User(String name, String psw) {

super();

this.name = name;

this.psw = psw;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getPsw() {

return psw;

}

public void setPsw(String psw) {

this.psw = psw;

}

@Override

public String toString() {

return "User [name=" + name + ", psw=" + psw + "]";

}

@Override

public int hashCode() {

final int prime = 31;

int result = 1;

result = prime * result + ((name == null) ? 0 : name.hashCode());

result = prime * result + ((psw == null) ? 0 : psw.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;

User other = (User) obj;

if (name == null) {

if (other.name != null)

return false;

} else if (!name.equals(other.name))

return false;

if (psw == null) {

if (other.psw != null)

return false;

} else if (!psw.equals(other.psw))

return false;

return true;

}

}

3.4.2 序列化存储

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectOutputStream;

/*

* 序列化和反序列化

* 序列化: 从内存保存到硬盘

* 反序列化 : 从硬盘读取到内存 .

* 操作的数据都是对象 . 都是Object

*

*/

public class Demo {

public static void main(String[] args) throws IOException {

// 创建序列化 流对象

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.txt"));

User user = new User("老王", "laowang");//java.io.NotSerializableException: cn.javahelp_02.User

oos.writeObject(user);

oos.close();

}

}

3.4.3 反序列化读取

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.ObjectInputStream;

/*

* 读取序列化的信息, 反序列化.

*/

public class Demo2 {

public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {

// 创建反序列化 流 .

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.txt"));

Object obj = ois.readObject();

System.out.println(obj);

if (obj instanceof User) {

User u = (User) obj;

String name = u.getName();

System.out.println(name);

}

ois.close();

}

}

3.4.4 在创建对象读取(报读取文件结尾异常)思考:不知道里面存储多少元素,但是读到结尾就报异常,这样怎么办。

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.ObjectInputStream;

/*

* 读取序列化的信息, 反序列化.

*/

public class Demo2 {

public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {

// 创建反序列化 流 .

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.txt"));

Object obj = ois.readObject();

System.out.println(obj);

if (obj instanceof User) {

User u = (User) obj;

String name = u.getName();

System.out.println(name);

}

Object obj2 = ois.readObject(); //End Of File Exception 读取文件结尾异常

System.out.println(obj2);

ois.close();

}

}

3.4.5 集合序列化解决不知道存储元素数问题

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.util.ArrayList;

/*

* 把集合序列化.

*/

public class Demo3 {

public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {

ArrayList<User > arrayList = new ArrayList<>();

User user = new User("金莲","jinlian");

User user2 = new User("西门","daguanren");

User user3 = new User("大郎","cuibing");

arrayList.add(user);

arrayList.add(user2);

arrayList.add(user3);

//创建 序列化流

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user2.txt"));

oos.writeObject(arrayList);

oos.close();

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user2.txt"));

Object readObject = ois.readObject();

System.out.println(readObject);

// 强制 转换 在遍历 readObject --> ArrayList<User>

ArrayList<User> userList = (ArrayList<User>) readObject;

for (User u : userList) {

System.out.println(u.getName() +" -- "+ u.getPsw());

}

}

}

3.5 序列化接口

当一个对象要能被序列化,这个对象所属的类必须实现Serializable接口。否则会发生异常NotSerializableException异常。

同时当反序列化对象时,如果对象所属的class文件在序列化之后进行了修改,那么进行反序列化也会发生异常InvalidClassException。发生这个异常的原因如下:

  • 该类的序列版本号与从流中读取的类描述符的版本号不匹配
  • 该类包含未知数据类型
  • 该类没有可访问的无参数构造方法

Serializable标记接口。该接口给需要序列化的类,提供了一个序列版本号。serialVersionUID. 该版本号的目的在于验证序列化的对象和对应类是否版本匹配。

标记作用,当年的类没变,虽然添加了属性,但是可以

public class Person implements Serializable {

/*

* serialVersionUID = 1L

* 只是一个对象的标记. 防止 你的类升级了, 对象 与类的信息 不一致.

*/

//给类显示声明一个序列版本号。

private static final long serialVersionUID = 1L;

private String name;

private 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 + "]";

}

}

3.6 瞬态关键字transient

当一个类的对象需要被序列化时,某些属性不需要被序列化,这时不需要序列化的属性可以使用关键字transient修饰。只要被transient修饰了,序列化时这个属性就不会琲序列化了。

同时静态修饰也不会被序列化,因为序列化是把对象数据进行持久化存储,而静态的属于类加载时的数据,不会被序列化。

public class Person implements Serializable {

/*

* 给类显示声明一个序列版本号。

*

*只要被transient修饰了,序列化时这个属性就不会琲序列化了。不想保存

*/

private static final long serialVersionUID = 1L;

private static 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 + "]";

}

}

第4章 Properties

4.1 概念及常用方法

Properties是双列集合的一种,是Hashtable的子类。属性集:key---value

该类没有泛型,通过setProperty / getProperty/ stringPropertyNames完成针对字符串的操作。

它是一个可以持久化的属性集。键值可以存储到集合中,也可以存储到持久化的设备(硬盘、U盘、光盘)上。包含IO相关方法:

  • load(InputStream) 把指定流所对应的文件中的数据,读取出来,保存到Properties集合中
  • load(Reader)
  • store(OutputStream,commonts)把集合中的数据,保存到指定的流所对应的文件中,参数commonts代表对描述信息
  • store(Writer,comments);

注意:使用字符流FileReader就可以完成文件中文的读取操作了

4.2 使用方法举例

/*

* Properties集合,它是唯一一个能与IO流交互的集合

*/

public class PropertiesDemo01 {

public static void main(String[] args) {

//创建集合对象

Properties prop = new Properties();

//添加元素到集合

//prop.put(key, value); //setProperty底层调用put方法

prop.setProperty("周迅", "张学友");

prop.setProperty("李小璐", "贾乃亮");

prop.setProperty("杨幂", "刘恺威");

//System.out.println(prop);//测试的使用

//遍历集合

Set<String> keys = prop.stringPropertyNames();

for (String key : keys) {

//通过键 找值

//prop.get(key)

String value = prop.getProperty(key);

System.out.println(key+"==" +value);

}

}

}

4.3 将配置文件中的数据存储到文件中

/**

* 需求:使用Properties集合,完成把集合内容存储到IO流所对应文件中的操作

*

* 分析:

* 1,创建Properties集合

* 2,添加元素到集合

* 3,创建流

* 4,通过store方法把集合中的数据存储到流所对应的文件中

* 5,关闭流

*/

public class PropertiesDemo02 {

public static void main(String[] args) throws IOException {

//1,创建Properties集合

Properties prop = new Properties();

//2,添加元素到集合

prop.setProperty("周迅", "张学友");

prop.setProperty("李小璐", "贾乃亮");

prop.setProperty("杨幂", "刘恺威");

//3,创建流

FileWriter out = new FileWriter("prop.properties");

//4,把集合中的数据存储到流所对应的文件中

prop.store(out, "save data");

//5,关闭流

out.close();

}

}

4.4 读取配置文件中的数据,同时更新数据,并保存

/*

* 需求:从属性集文件prop.properties 中取出数据,保存到集合中

* 分析:

* 1,创建集合

* 2,创建流对象

* 3,把流所对应文件中的数据 读取到集合中

* load(InputStream) 把指定流所对应的文件中的数据,读取出来,保存到Propertie集合中

load(Reader)

* 4,关闭流

* 5,显示集合中的数据

*/

public class PropertiesDemo03 {

public static void main(String[] args) throws IOException {

//1,创建集合

Properties prop = new Properties();

//2,创建流对象

FileInputStream in = new FileInputStream("prop.properties");

//FileReader in = new FileReader("prop.properties");

//3,把流所对应文件中的数据 读取到集合中

prop.load(in);

//4,关闭流

in.close();

//5,显示集合中的数据

System.out.println(prop);

}

}

第5章 CommonsIO

5.1 CommonsIO概述

除JDK开发者与我们使用JDK的人员以外,其他第三方组织或个人提供了大量开源免费的类库,供我们使用。Apache组织。CommonsIO是非常优秀的IO操作库,提供了大量简洁的IO操作方法。

5.2 使用方式(导入jar包)

1.解压commonsio压缩包

2.在eclipse项目中创建lib文件夹,并将commons-io.jar拷贝到lib文件夹

3.右键点击commons-io.jar,Build Path→Add to Build Path

4.完成

5.3 FilenameUtils

这个工具类是用来处理文件名的,他可以轻松解决不同操作系统文件名称规范不同的问题

  • 常用方法:

getExtension(String path):获取文件的扩展名;

getName():获取文件名;

isExtension(String fileName,String ext):判断fileName是否是ext后缀名;

import org.apache.commons.io.FilenameUtils;

/*

*

* Commons-IO 测试.

*

* FileNameUtils

*/

public class Demo {

public static void main(String[] args) {

String extension = FilenameUtils.getExtension("aa.txt");

System.out.println(extension);

boolean extension2 = FilenameUtils.isExtension("aa.png", "PNG");

System.out.println(extension2);

}

}

5.4 FileUtils

提供文件操作(移动文件,读取文件,检查文件是否存在等等)的方法。

  • 常用方法:

readFileToString(File file):读取文件内容,并返回一个String;

writeStringToFile(File file,String content):将内容content写入到file中;

copyDirectoryToDirectory(File srcDir,File destDir);文件夹复制 (带外层文件夹)

copyDirectory(File srcDir,File destDir);文件夹复制(不带外层文件夹)

copyFileToFile(File srcFile,File destFile);文件夹复制

/*

* 完成文件、文件夹的复制

*/

public class CommonsIODemo02 {

public static void main(String[] args) throws IOException {

//通过Commons-IO完成了文件复制的功能

FileUtils.copyFile(new File("D:\\test.avi"), new File("D:\\copy.avi"));

//通过Commons-IO完成了文件夹复制的功能

//D:\基础班 复制到 C:\\abc文件夹下

FileUtils.copyDirectoryToDirectory(new File("D:\\a"), new File("C:\\a"));

}

}

第6章 IO综合案例---文件管理器

6.1 IO综合案例---文件管理器

6.1.1 案例介绍与演示

此程序在DOS下实现:指定关键字检索文件;指定后缀名检索文件;复制文件/目录;

6.1.2 案例分析

1.基本功能1与基本功能2均为指定文件夹后的文件夹内容遍历

2.基本功能3可使用自定义方法,也可以使用第三方发Java包。

3.附加功能,请在功能1中统计出包含指定关键字的文件夹与文件的个数

6.1.3 案例实现

import java.io.File;

import java.io.IOException;

import java.util.Scanner;

import org.apache.commons.io.FileUtils;

/*

* 文件管理器

*

* 分析: 按照文档功能 实现

* 实现 : 1. 页面 操作项

*

* 2. 实现不同选项中的功能

*/

public class Demo {

static Scanner sc = new Scanner(System.in);

public static void main(String[] args) {

while (true) {

System.out.println("文件管理器_控制台版");

System.out.print("(1)指定关键字检索文件\t");

System.out.print("(2)指定后缀名检索文件\t");

System.out.print("(3)复制文件/目录\t");

System.out.println("(4)退出");

System.out.println("请选择操作项: ");

String opt = sc.nextLine();

switch (opt) {

case "1": // 指定关键字检索文件\t

System.out.println("文件检索,请输入目录....");

// 输入目录

String dirPath = sc.nextLine(); // 目录的路径

// 创建 File 对象

File srcDir = new File(dirPath);

if (!srcDir.exists()) {

System.out.println("对不起 , 目录并不存在");

break;

}

// 简单的判断 ,是文件 就跳出

if (srcDir.isFile()) {

System.out.println("对不起 , 请输入目录, 不要输入文件名称");

break;

}

System.out.println("请输入关键字...");

// 输入关键字

String key = sc.nextLine();

findFileByKey(srcDir, key);

break;

case "2": // 指定后缀名 检索文件

System.out.println("文件检索,请输入目录....");

// 输入目录

String dir2 = sc.nextLine();

System.out.println("请输入后缀名...");

// 输入关键字

String ext = sc.nextLine();

findFileByExt(dir2, ext); // 请参照 1 实现

break;

case "3":

System.out.println("请输入源文件/ 目录");

String src = sc.nextLine();

System.out.println("请输入目标位置");

String dest = sc.nextLine();

// 把路径变成File 对象

File srcFile = new File(src);

// 判断

if (!srcFile.exists()) {

System.out.println("输入有源 路径有误 !!!");

break;

}

File destFile = new File(dest);

copyFile(srcFile, destFile);

break;

case "4":

System.out.println("退出");

System.exit(0);

break;

default:

System.out.println("操作输入有误!!!");

break;

}

}

}

private static void copyFile(File srcFile, File destFile) {

// 判断 . src 是文件

if (srcFile.isFile()) {

try {

FileUtils.copyFile(srcFile, destFile);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

} else {

// src 是文件夹

try {

FileUtils.copyDirectoryToDirectory(srcFile, destFile);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

private static void findFileByExt(String dir2, String ext) {

System.out.println("扩展名 ....找到了");

}

private static void findFileByKey(File dir, String key) {

System.out.println("关键字.... 找到了");

// 遍历 文件夹

File[] listFiles = dir.listFiles();

for (File file : listFiles) { // file 是 dir下一级的所有 文件或者文件夹.

// 如果 文件 , 是否包含关键字.

if (file.isFile()) {

if (file.getName().contains(key)) {

// 包含 关键字 ,输出绝对路径

System.out.println(file.getAbsolutePath());

}

} else {

// 如果文件夹 , 调用自己 .

findFileByKey(file, key); // 注意: file 是 你要遍历的文件夹了.

}

}

}

}

6.2 键盘录入3个学生信息(学号,姓名,年龄,居住城市)存入集合。然后遍历集合把每一个学生信息存入文本文件(每一个学生信息为一行,自己定义分割标记)

  • 定义学生类

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;

}

}

public class Demo01ArrayListToFile {

public static void main(String[] args) throws IOException {

//创建集合对象

ArrayList<Student> list = new ArrayList<Student>();

//写方法实现键盘录入学生信息,并把学生对象作为元素添加到集合

addStudent(list);

addStudent(list);

addStudent(list);

//创建输出缓冲流对象

BufferedWriter bw = new BufferedWriter(new FileWriter("array.txt"));

//遍历集合,得到每一个学生信息,并把学生信息按照一定的格式写入文本文件

for(int x=0; x<list.size(); x++) {

Student s = list.get(x);

//heima001,向问天,30,北京

StringBuilder builder = new StringBuilder();

builder.append(s.getId()).append(",").append(s.getName()).append(",").append(s.getAge()).append(",").append(s.getAddress());

bw.write(builder.toString());

bw.newLine();

bw.flush();

}

//释放资源

bw.close();

}

//添加学生

public static void addStudent(ArrayList<Student> list) {

//创建键盘录入对象

Scanner sc = new Scanner(System.in);

//为了让id能够被访问到,我们就把id定义在了循环的外面

String id;

//为了让代码能够回到这里,用循环

while(true) {

System.out.println("请输入学生学号:");

id = sc.nextLine();

//判断学号有没有被人占用

//定义标记

boolean flag = false;

//遍历集合,得到每一个学生

for(int x=0; x<list.size(); x++) {

Student s = list.get(x);

//获取该学生的学号,和键盘录入的学号进行比较

if(s.getId().equals(id)) {

flag = true; //说明学号被占用了

break;

}

}

if(flag) {

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);

//把学生对象作为元素添加到集合

list.add(s);

//给出提示

System.out.println("添加学生成功");

}

}

6.3 把上一题的文本文件中的学生信息读取出来存储到集合中,然后遍历集合,在控制台输出

public class Demo02FileToArrayList {

public static void main(String[] args) throws IOException {

//创建输入缓冲流对象

BufferedReader br = new BufferedReader(new FileReader("array.txt"));

//创建集合对象

ArrayList<Student> list = new ArrayList<Student>();

//读取文件数据,并把数据按照一定的格式进行分割赋值给学生对象,然后把学生对象作为元素存储到集合

String line;

while((line=br.readLine())!=null) {

//分割字符串

String[] strArray = line.split(",");

//创建学生对象并赋值

Student s = new Student();

s.setId(strArray[0]);

s.setName(strArray[1]);

s.setAge(strArray[2]);

s.setAddress(strArray[3]);

//把学生对象作为元素存储到集合

list.add(s);

}

//释放资源

br.close();

//遍历集合

System.out.println("学号\t\t姓名\t年龄\t居住地");

for(int x=0; x<list.size(); x++) {

Student s = list.get(x);

System.out.println(s.getId()+"\t"+s.getName()+"\t"+s.getAge()+"\t"+s.getAddress());

}

}

}

6.4 学生管理系统IO版

  • 定义学生类

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;

}

}

  • 学生管理系统IO版本代码实现

public class StudentManager {

public static void main(String[] args) throws IOException{

//定义文件路径

String fileName = "students.txt";

//为了让程序能够回到这里来,我们使用循环

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 choiceString = sc.nextLine();

//用switch语句实现选择

switch(choiceString) {

case "1":

//查看所有学生

findAllStudent(fileName);

break;

case "2":

//添加学生

addStudent(fileName);

break;

case "3":

//删除学生

deleteStudent(fileName);

break;

case "4":

//修改学生

updateStudent(fileName);

break;

case "5":

default:

System.out.println("谢谢你的使用");

System.exit(0); //JVM退出

break;

}

}

}

//从文件中读数据到集合

public static void readData(String fileName,ArrayList<Student> list) throws IOException {

//创建输入缓冲流对象

BufferedReader br = new BufferedReader(new FileReader(fileName));

String line;

while((line=br.readLine())!=null) {

String[] datas = line.split(",");

Student s = new Student();

s.setId(datas[0]);

s.setName(datas[1]);

s.setAge(datas[2]);

s.setAddress(datas[3]);

list.add(s);

}

br.close();

}

//把集合中的数据写入文件

public static void writeData(String fileName,ArrayList<Student> list) throws IOException {

//创建输出缓冲流对象

BufferedWriter bw = new BufferedWriter(new FileWriter(fileName));

for(int x=0; x<list.size(); x++) {

Student s = list.get(x);

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 updateStudent(String fileName) throws IOException {

//创建集合对象

ArrayList<Student> list = new ArrayList<Student>();

//从文件中把数据读取到集合中

readData(fileName, list);

//修改学生的思路:键盘录入一个学号,到集合中去查找,看是否有学生使用的是该学号,如果有就修改该学生

//创建键盘录入对象

Scanner sc = new Scanner(System.in);

System.out.println("请输入你要修改的学生的学号:");

String id = sc.nextLine();

//定义一个索引

int index = -1;

//遍历集合

for(int x=0; x<list.size(); x++) {

//获取每一个学生对象

Student s = list.get(x);

//拿学生对象的学号和键盘录入的学号进行比较

if(s.getId().equals(id)) {

index = x;

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);

//修改集合中的学生对象

list.set(index, s);

//把集合中的数据重新写回到文件

writeData(fileName, list);

//给出提示

System.out.println("修改学生成功");

}

}

//删除学生

public static void deleteStudent(String fileName) throws IOException {

//创建集合对象

ArrayList<Student> list = new ArrayList<Student>();

//从文件中把数据读取到集合中

readData(fileName, list);

//删除学生的思路:键盘录入一个学号,到集合中去查找,看是否有学生使用的是该学号,如果有就删除该学生

//创建键盘录入对象

Scanner sc = new Scanner(System.in);

System.out.println("请输入你要删除的学生的学号:");

String id = sc.nextLine();

//我们必须给出学号不存在的时候的提示

//定义一个索引

int index = -1;

//遍历集合

for(int x=0; x<list.size(); x++) {

//获取到每一个学生对象

Student s = list.get(x);

//拿这个学生对象的学号和键盘录入的学号进行比较

if(s.getId().equals(id)) {

index = x;

break;

}

}

if(index == -1) {

System.out.println("不好意思,你要删除的学号对应的学生信息不存在,请回去重新你的选择");

}else {

list.remove(index);

//把集合中的数据重新写回到文件

writeData(fileName, list);

System.out.println("删除学生成功");

}

}

//添加学生

public static void addStudent(String fileName) throws IOException {

//创建集合对象

ArrayList<Student> list = new ArrayList<Student>();

//从文件中把数据读取到集合中

readData(fileName, list);

//创建键盘录入对象

Scanner sc = new Scanner(System.in);

//为了让id能够被访问到,我们就把id定义在了循环的外面

String id;

//为了让代码能够回到这里,用循环

while(true) {

System.out.println("请输入学生学号:");

id = sc.nextLine();

//判断学号有没有被人占用

//定义标记

boolean flag = false;

//遍历集合,得到每一个学生

for(int x=0; x<list.size(); x++) {

Student s = list.get(x);

//获取该学生的学号,和键盘录入的学号进行比较

if(s.getId().equals(id)) {

flag = true; //说明学号被占用了

break;

}

}

if(flag) {

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);

//把学生对象作为元素添加到集合

list.add(s);

//把集合中的数据重新写回到文件

writeData(fileName, list);

//给出提示

System.out.println("添加学生成功");

}

//查看所有学生

public static void findAllStudent(String fileName) throws IOException {

//创建集合对象

ArrayList<Student> list = new ArrayList<Student>();

//从文件中把数据读取到集合中

readData(fileName, list);

//首先来判断集合中是否有数据,如果没有数据,就给出提示,并让该方法不继续往下执行

if(list.size() == 0) {

System.out.println("不好意思,目前没有学生信息可供查询,请回去重新选择你的操作");

return;

}

//\t 其实就是一个tab键的位置

System.out.println("学号\t\t姓名\t年龄\t居住地");

for(int x=0; x<list.size(); x++) {

Student s = list.get(x);

System.out.println(s.getId()+"\t"+s.getName()+"\t"+s.getAge()+"\t"+s.getAddress());

}

}

}

第7章 IO总结

  • 字节流
    • 字节输入流 InputStream
      • FileInputStream 操作文件的字节输入流
      • BufferedInputStream高效的字节输入流
      • ObjectInputStream 反序列化流
    • 字节输出流 OutputStram
      • FileOutputStream 操作文件的字节输出流
      • BufferedOutputStream 高效的字节输出流
      • ObjectOuputStream 序列化流
      • PrintStream 字节打印流
  • 字符流
    • 字符输入流 Reader
      • FileReader 操作文件的字符输入流
      • BufferedReader 高效的字符输入流
      • InputStreamReader 输入操作的转换流(把字节流封装成字符流)
    • 字符输出流 Writer
      • FileWriter 操作文件的字符输出流
      • BufferedWriter 高效的字符输出流
      • OutputStreamWriter 输出操作的转换流(把字节流封装成字符流)
      • PrintWriter 字符打印流
  • 方法:
    • 读数据方法:
      • read() 一次读一个字节或字符的方法
      • read(byte[] char[]) 一次读一个数组数据的方法
      • readLine() 一次读一行字符串的方法(BufferedReader类特有方法)
      • readObject() 从流中读取对象(ObjectInputStream特有方法)
    • 写数据方法:
      • write(int) 一次写一个字节或字符到文件中
      • write(byte[] char[]) 一次写一个数组数据到文件中
      • write(String) 一次写一个字符串内容到文件中
      • writeObject(Object ) 写对象到流中(ObjectOutputStream类特有方法)
      • newLine() 写一个换行符号(BufferedWriter类特有方法)
  • 向文件中写入数据的过程
    • 1.创建输出流对象
    • 2.写数据到文件
    • 3.关闭输出流
  • 从文件中读数据的过程
    • 1.创建输入流对象
    • 2.从文件中读数据
    • 3.关闭输入流
  • 文件复制的过程
    • 1.创建输入流(数据源)
    • 2.创建输出流(目的地)
    • 3.从输入流中读数据
    • 4.通过输出流,把数据写入目的地
    • 5.关闭流
  • File类
    • 方法
      • 获取文件名称 getName()
      • 获取文件绝对路径 getAbsolutePath()
      • 获取文件大小 length()
      • 获取当前文件夹中所有File对象 File[] listFiles()
      • 判断是否为文件 isFile()
      • 判断是否为文件夹 isDirectory()
      • 创建文件夹 mkdir() mkdirs()
      • 创建文件 createNewFile()
  • 异常
    • try..catch…finally捕获
    • throws 声明异常
    • throw 抛出异常对象
  • 异常的分类
    • 编译期异常 Exception
      • 运行期异常 RuntimeException
  • 注意:
    • 编译期异常,必须处理,不然无法编译通过
    • 运行期异常,程序运行过程中,产生的异常信息
  • Properties:Map集合的一种,它是Hashtable集合的子集合,它键与值都是String类型,它是唯一能与IO流结合使用的集合
    • 方法
      • load( InputStream in ) 从流所对应的文件中,读数据到集合中
      • load( Reader in ) 从流所对应的文件中,读数据到集合中
      • store( OutputStream out , String message ) 把集合中的数据,写入到流所对应的文件中
      • store( Writer out , String message) 把集合中的数据,写入到流所对应的文件中
  • 实现文件内容的自动追加
    • 构造方法
      • FileOutputStream(File file, boolean append)
      • FileOutputStream(String fileName, boolean append)
      • FileWriter(File, boolean append)
      • FileWriter(String fileName, boolean append)
  • 实现文件内容的自动刷新
    • 构造方法
      • PrintWriter(OutputStream out, boolean autoFlush)
      • PrintWriter(Writer out, boolean autoFlush)
  • Commons-IO
    • 方法
      • readFileToString(File file):读取文件内容,并返回一个String;
      • writeStringToFile(File file,String content):将内容content写入到file中;
      • copyDirectoryToDirectory(File srcDir,File destDir);文件夹复制
      • copyFileToDirectory (File srcFile,File destFile);文件复制

第8章 本日自习作业:

8.1 知识点相关题

8.1.1 打印流:PrintStream和PrintWriter

题目:

1) 定义类Test3,定义main()方法,按以下要求编写代码:

  • 构造一个PrintStream字节打印流,指向某个文件;
  • 使用out.println方法向文件中打印一句话;
  • 关闭流;
  • 运行程序,查看新文件;
  • 将打印方式改为:字符打印流 PrintWriter;

8.1.2 字对象的序列化和反序列化

题目:

定义类Student,属性 String name,int age提供get set方法, 满参构造方法,toString(),

根据第一题中的学生信息:

实现对象的序列化将60分以下的学生对象写到文件student.txt中

实现对象的反序列化,读取student.txt文件,获取学生对象信息.打印在控制台.

1:使用带刷新的打印流操作,完成文本打印到控制台

2:完成对象序列化到任意文件,修改代码中该类的某个属性访问权限,由私有化改为公共修饰,再从文件中读取该对象,打印对象内容

3:使用properties的方法将集合内容存储到文件中并重新读取

4:使用CommonsIO完成文件三个以上方法的调用

5:复习所有IO类,以普通输入输出流为主

6:完成课上最后综合案例case2和附加功能

7:查漏补缺面向对象、集合、IO相关知识点

8.2 代码题

8.2.1 通过CommonsIO完成文件和文件夹的复制.

答案:

代码语言:javascript
复制
public class copy {

    public static void main(String[] args) throws IOException {

//封装路径

File file1 = new File("C:\\a.txt");

File file2 = new File("D:\\a.txt");

//复制文件

FileUtils.copyFile(file1,file2);

//复制文件夹

FileUtils.copyDirectoryToDirectory(new File("C:\\文件夹"), new File("D:\\文件夹"));

    }

}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-06-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java帮帮 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第1章 流的复习总结
  • 第2章 打印流
    • 2.1 打印流的概述
      • 2.2 打印流完成数据自动刷新
      • 第3章 序列化流
        • 3.1 序列化流概念
          • 3.2 序列化流
            • 3.3 对象反序列化流
              • 3.4 将用户信息存储到文件中与读取文件用户
                • 3.4.1 用户实体类
                • 3.4.2 序列化存储
                • 3.4.3 反序列化读取
                • 3.4.4 在创建对象读取(报读取文件结尾异常)思考:不知道里面存储多少元素,但是读到结尾就报异常,这样怎么办。
                • 3.4.5 集合序列化解决不知道存储元素数问题
              • 3.5 序列化接口
                • 3.6 瞬态关键字transient
                • 第4章 Properties
                  • 4.1 概念及常用方法
                    • 4.2 使用方法举例
                      • 4.3 将配置文件中的数据存储到文件中
                        • 4.4 读取配置文件中的数据,同时更新数据,并保存
                        • 第5章 CommonsIO
                          • 5.1 CommonsIO概述
                            • 5.2 使用方式(导入jar包)
                              • 5.3 FilenameUtils
                                • 5.4 FileUtils
                                • 第6章 IO综合案例---文件管理器
                                  • 6.1 IO综合案例---文件管理器
                                    • 6.1.1 案例介绍与演示
                                    • 6.1.2 案例分析
                                    • 6.1.3 案例实现
                                  • 6.2 键盘录入3个学生信息(学号,姓名,年龄,居住城市)存入集合。然后遍历集合把每一个学生信息存入文本文件(每一个学生信息为一行,自己定义分割标记)
                                    • 6.3 把上一题的文本文件中的学生信息读取出来存储到集合中,然后遍历集合,在控制台输出
                                      • 6.4 学生管理系统IO版
                                      • 第7章 IO总结
                                      • 第8章 本日自习作业:
                                        • 8.1 知识点相关题
                                          • 8.1.1 打印流:PrintStream和PrintWriter
                                          • 8.1.2 字对象的序列化和反序列化
                                        • 8.2 代码题
                                          • 8.2.1 通过CommonsIO完成文件和文件夹的复制.
                                      相关产品与服务
                                      数据保险箱
                                      数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
                                      领券
                                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档