本实验目标在实验 (2) 基础上,加入I/O流的操作,实现本地下载和上传文件的功能。可下载文件存放在磁盘 (笔者采用F盘) 的 uploadfile 文件夹,选择下载后可将指定文件下载至磁盘的 downloadfile文件夹中;选择上传则可将自己指定的文件上传至磁盘的 uploadfile 文件夹中。
同时新加入了 Doc 类,用于记录文件信息,用哈希表 docs 存储在DataProcessing类中,并加入了一系列对文件 Doc 信息增删的方法。
首先新增加了 Doc 文件类:
改进后的模块结构图:
I/O层次结构体系:
本次实验代码基于实验 (2) 修改。
import java.sql.*;
import java.util.*;
public class DataProcessing {
private static boolean connectToDB = false;
static Hashtable<String, User> users;
static Hashtable<String, Doc> docs; // 文件类哈希表
static {
users = new Hashtable<String, User>();
users.put("jack", new Operator("jack", "123", "operator"));
users.put("rose", new Browser("rose", "123", "browser"));
users.put("kate", new Administrator("kate", "123", "administrator"));
Init();
// 获取当前时间
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
docs = new Hashtable<String, Doc>();
docs.put("0001", new Doc("0001", "jack", timestamp, "Doc Source Java", "Doc.txt")); // 初始文件
}
public static void Init() {
if (Math.random() > 0.2)
connectToDB = true;
else
connectToDB = false;
}
// 查找文件
public static Doc searchDoc(String ID) throws SQLException {
if (docs.containsKey(ID)) {
Doc temp = docs.get(ID);
return temp;
}
return null;
}
// 获取所有文件
public static Enumeration<Doc> getAllDocs() throws SQLException {
Enumeration<Doc> e = docs.elements();
return e;
}
// 增添新文件
public static boolean insertDoc(String ID, String creator, Timestamp timestamp, String description, String filename)
throws SQLException {
Doc doc;
if (docs.containsKey(ID))
return false;
else {
doc = new Doc(ID, creator, timestamp, description, filename);
docs.put(ID, doc);
return true;
}
}
public static User searchUser(String name) throws SQLException {
if (!connectToDB)
throw new SQLException("未连接到数据库!");
double ranValue = Math.random();
if (ranValue > 0.8)
throw new SQLException("执行查询时出错!");
if (users.containsKey(name)) {
return users.get(name);
}
return null;
}
public static User searchUser(String name, String password) throws SQLException {
if (!connectToDB)
throw new SQLException("未连接到数据库!");
double ranValue = Math.random();
if (ranValue > 0.8)
throw new SQLException("执行查询时出错!");
if (users.containsKey(name)) {
User temp = users.get(name);
if ((temp.getPassword()).equals(password))
return temp;
}
return null;
}
public static Enumeration<User> getAllUser() throws SQLException {
if (!connectToDB)
throw new SQLException("未连接到数据库!");
double ranValue = Math.random();
if (ranValue > 0.8)
throw new SQLException("执行查询时出错!");
Enumeration<User> e = users.elements();
return e;
}
public static boolean updateUser(String name, String password, String role) throws SQLException {
if (!connectToDB)
throw new SQLException("未连接到数据库!");
double ranValue = Math.random();
if (ranValue > 0.8)
throw new SQLException("执行更新时出错!");
User user;
if (users.containsKey(name)) {
if (role.equalsIgnoreCase("administrator"))
user = new Administrator(name, password, role);
else if (role.equalsIgnoreCase("operator"))
user = new Operator(name, password, role);
else if (role.equalsIgnoreCase("browser"))
user = new Browser(name, password, role);
else
return false;
users.put(name, user);
return true;
} else
return false;
}
public static boolean insertUser(String name, String password, String role) throws SQLException {
if (!connectToDB)
throw new SQLException("未连接到数据库!");
double ranValue = Math.random();
if (ranValue > 0.8)
throw new SQLException("执行插入时出错!");
User user;
if (users.containsKey(name))
return false;
else {
if (role.equalsIgnoreCase("administrator"))
user = new Administrator(name, password, role);
else if (role.equalsIgnoreCase("operator"))
user = new Operator(name, password, role);
else if (role.equalsIgnoreCase("browser"))
user = new Browser(name, password, role);
else
return false;
users.put(name, user);
return true;
}
}
public static boolean deleteUser(String name) throws SQLException {
if (!connectToDB)
throw new SQLException("未连接到数据库!");
double ranValue = Math.random();
if (ranValue > 0.8)
throw new SQLException("执行删除时出错!");
if (users.containsKey(name)) {
users.remove(name);
return true;
} else
return false;
}
public static void disconnectFromDB() throws SQLException {
if (connectToDB) {
if (Math.random() > 0.8) {
throw new SQLException("断开数据库连接时出错!");
}
connectToDB = false;
}
}
}
新增加 docs 哈希表,以及文件档案操作方法 searchDoc()、getAllDocs()、insertDoc()。
import java.sql.Timestamp;
public class Doc {
private String ID;
private String creator;
private Timestamp timestamp;
private String description;
private String filename;
public Doc(String ID, String creator, Timestamp timestamp, String description, String filename) {
this.setID(ID);
this.setCreator(creator);
this.setTimestamp(timestamp);
this.setDescription(description);
this.setFilename(filename);
}
public String getID() {
return ID;
}
public void setID(String iD) {
ID = iD;
}
public String getCreator() {
return creator;
}
public void setCreator(String creator) {
this.creator = creator;
}
public Timestamp getTimestamp() {
return timestamp;
}
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String toString() {
return "ID:" + this.ID + " Creator:" + this.creator + " Time:" + this.timestamp + " Filename:" + this.filename
+ " Description:" + this.description;
}
}
Doc 类记录了档案文件的5类属性,需要注意 timestamp 记录的是文件创建时的时间,该成员属于 Timestamp 类。
因此在后续新增文件时,也要记得记录当前时间,作为其 timestamp 成员。
import java.io.*;
import java.sql.SQLException;
import java.util.*;
public abstract class User {
private String name;
private String password;
private String role;
// 上传与下载路径
String uploadpath = "f:\\uploadfile\\";
String downloadpath = "f:\\downloadfile\\";
User(String name, String password, String role) {
this.setName(name);
this.setPassword(password);
this.setRole(role);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public abstract void showMenu();
public String toString() {
return "Name: " + this.name + " Password: " + this.password + " Role: " + this.role;
}
@SuppressWarnings("resource")
public boolean downloadFile() {
Scanner scan = new Scanner(System.in);
System.out.print("请输入档案号:");
String download_id = scan.next();
Doc download_doc = null;
try {
download_doc = DataProcessing.searchDoc(download_id);
} catch (SQLException e) {
System.out.println(e.getLocalizedMessage());
}
if (download_doc == null) {
return false;
} else {
// 输入文件对象
File input_file = new File(uploadpath + download_doc.getFilename());
try {
// 输入过滤器流,建立在文件流上
BufferedInputStream input = new BufferedInputStream(new FileInputStream(input_file));
// 输出文件对象
File output_file = new File(downloadpath + download_doc.getFilename());
// 创建文件
output_file.createNewFile();
// 输出过滤器流,建立在文件流上
BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(output_file));
// 用字节数组存取数据
byte[] bytes = new byte[1024];
// 文件写入操作
int length = 0;
while ((length = input.read(bytes)) != -1) {
output.write(bytes, 0, length);
}
// 关闭流
input.close();
output.close();
return true;
} catch (FileNotFoundException e) {
System.out.println(e.getLocalizedMessage());
} catch (IOException e) {
System.out.println(e.getLocalizedMessage());
}
return false;
}
}
public void showFileList() {
try {
Enumeration<Doc> e = DataProcessing.getAllDocs();
while (e.hasMoreElements()) {
System.out.println(e.nextElement());
}
} catch (SQLException s) {
System.out.println(s.getLocalizedMessage());
}
}
public boolean changeSelfInfo(String password) {
try {
if (DataProcessing.updateUser(name, password, role)) {
this.password = password;
return true;
} else
return false;
} catch (SQLException e) {
System.out.println(e.getLocalizedMessage());
}
return false;
}
public void exitSystem() {
System.out.println("系统退出, 谢谢使用 ! ");
System.exit(0);
}
}
User 类增加了下载文件的具体操作,涉及 I/O 流的操作。
Java 的输入输出流类别有很多,操作写法也不唯一,这里就不对相关知识做详细讲解了,参考一下代码相信很容易理解。
import java.sql.SQLException;
import java.util.*;
public class Administrator extends User {
public Administrator(String name, String password, String role) {
super(name, password, role);
}
public void updateUser(String input_name, String input_password, String input_role) {
try {
if (DataProcessing.updateUser(input_name, input_password, input_role)) {
System.out.println("修改成功!");
} else {
System.out.println("修改失败!输入角色不正确!");
}
} catch (SQLException e) {
System.out.println(e.getLocalizedMessage());
}
}
public void delUser(String input_name) {
try {
if (DataProcessing.deleteUser(input_name)) {
System.out.println("删除成功!");
} else {
System.out.println("删除失败!查找不到用户名!");
}
} catch (SQLException e) {
System.out.println(e.getLocalizedMessage());
}
}
public void addUser(String input_name, String input_password, String input_role) {
try {
if (DataProcessing.insertUser(input_name, input_password, input_role)) {
System.out.println("添加成功!");
} else {
System.out.println("添加失败!用户名已存在/角色名不正确!");
}
} catch (SQLException e) {
System.out.println(e.getLocalizedMessage());
}
}
public void listUser() {
try {
Enumeration<User> s = DataProcessing.getAllUser();
while (s.hasMoreElements()) {
System.out.println(s.nextElement());
}
} catch (SQLException e) {
System.out.println(e.getLocalizedMessage());
}
}
@SuppressWarnings("resource")
@Override
public void showMenu() {
Scanner scan1 = new Scanner(System.in);
Scanner scan2 = new Scanner(System.in);
Scanner scan3 = new Scanner(System.in);
Scanner scan4 = new Scanner(System.in);
// 控制界面开关
boolean administrator_isopen = true;
// 记录用户选择
String administrator_choice;
while (administrator_isopen) {
// 界面显示
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.文件列表");
System.out.println(" 7.修改密码");
System.out.println(" 8.退 出");
System.out.println("====================================");
System.out.print("请输入选项:");
administrator_choice = scan1.next();
if (administrator_choice.equals("1")) {
System.out.print("请输入用户名:");
String input_name = scan2.next();
System.out.print("请输入密码:");
String input_password = scan3.next();
try {
if (DataProcessing.searchUser(input_name, input_password) != null) {
System.out.print("请输入身份:");
String input_role = scan4.next();
this.updateUser(input_name, input_password, input_role);
} else {
System.out.println("用户名与密码不符!");
}
} catch (SQLException e) {
System.out.println(e.getLocalizedMessage());
}
} else if (administrator_choice.equals("2")) {
System.out.print("请输入用户名:");
String input_name = scan2.next();
this.delUser(input_name);
} else if (administrator_choice.equals("3")) {
System.out.print("请输入用户名:");
String input_name = scan2.next();
System.out.print("请输入密码:");
String input_password = scan3.next();
System.out.print("请输入身份:");
String input_role = scan4.next();
this.addUser(input_name, input_password, input_role);
} else if (administrator_choice.equals("4")) {
this.listUser();
} else if (administrator_choice.equals("5")) {
if (super.downloadFile()) {
System.out.println("下载成功!");
} else {
System.out.println("下载失败!");
}
} else if (administrator_choice.equals("6")) {
super.showFileList();
} else if (administrator_choice.equals("7")) {
System.out.print("请输入新密码:");
String newpassword = scan2.next();
if (super.changeSelfInfo(newpassword)) {
System.out.println("修改成功!");
} else {
System.out.println("修改失败");
}
} else if (administrator_choice.equals("8")) {
administrator_isopen = false;
} else {
System.out.println("输入格式有误!请重新输入!");
}
}
}
}
import java.util.Scanner;
public class Browser extends User {
public Browser(String name, String password, String role) {
super(name, password, role);
}
@SuppressWarnings("resource")
@Override
public void showMenu() {
Scanner scan1 = new Scanner(System.in);
Scanner scan2 = new Scanner(System.in);
// 控制界面开关
boolean browser_isopen = true;
// 记录用户选择
String browser_choice;
while (browser_isopen) {
// 界面显示
System.out.println("=======欢迎进入档案浏览员菜单=======");
System.out.println(" 1.下载文件");
System.out.println(" 2.文件列表");
System.out.println(" 3.修改密码");
System.out.println(" 4.退 出");
System.out.println("====================================");
System.out.print("请输入选项:");
browser_choice = scan1.next();
if (browser_choice.equals("1")) {
if (super.downloadFile()) {
System.out.println("下载成功!");
} else {
System.out.println("下载失败!");
}
} else if (browser_choice.equals("2")) {
super.showFileList();
} else if (browser_choice.equals("3")) {
System.out.print("请输入新密码:");
String newpassword = scan2.next();
if (super.changeSelfInfo(newpassword)) {
System.out.println("修改成功!");
} else {
System.out.println("修改失败");
}
} else if (browser_choice.equals("4")) {
browser_isopen = false;
} else {
System.out.println("输入格式有误!请重新输入!");
}
}
}
}
import java.io.*;
import java.sql.*;
import java.util.Scanner;
public class Operator extends User {
public Operator(String name, String password, String role) {
super(name, password, role);
}
@SuppressWarnings("resource")
public void uploadFile() {
Scanner scan1 = new Scanner(System.in);
Scanner scan2 = new Scanner(System.in);
Scanner scan3 = new Scanner(System.in);
System.out.print("请输入文件名(路径):");
String filename = scan1.next();
System.out.print("请输入档案号:");
String filenumber = scan2.next();
try {
if (DataProcessing.searchDoc(filenumber) != null) {
System.out.println("档案号重复!");
} else {
System.out.print("请输入档案描述:");
String fileDescription = scan3.next();
// 输入文件对象
File input_file = new File(filename);
// 输入过滤器流,建立在文件流上
BufferedInputStream input = new BufferedInputStream(new FileInputStream(input_file));
// 输出文件对象
File output_file = new File(uploadpath + input_file.getName());
// 创建文件
output_file.createNewFile();
// 输出过滤器流,建立在文件流上
BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(output_file));
// 用字节数组存取数据
byte[] bytes = new byte[1024];
// 文件写入操作
int length = 0;
while ((length = input.read(bytes)) != -1) {
output.write(bytes, 0, length);
}
// 关闭流
input.close();
output.close();
DataProcessing.docs.put(filenumber, new Doc(filenumber, this.getName(),
new Timestamp(System.currentTimeMillis()), fileDescription, input_file.getName()));
System.out.println("上传成功!");
}
} catch (SQLException | IOException e) {
System.out.println(e.getLocalizedMessage());
}
}
@SuppressWarnings("resource")
@Override
public void showMenu() {
Scanner scan1 = new Scanner(System.in);
Scanner scan2 = new Scanner(System.in);
// 控制界面开关
boolean operator_isopen = true;
// 记录用户选择
String operator_choice;
while (operator_isopen) {
// 界面显示
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("====================================");
System.out.print("请输入选项:");
operator_choice = scan1.next();
if (operator_choice.equals("1")) {
this.uploadFile();
} else if (operator_choice.equals("2")) {
if (super.downloadFile()) {
System.out.println("下载成功!");
} else {
System.out.println("下载失败!");
}
} else if (operator_choice.equals("3")) {
super.showFileList();
} else if (operator_choice.equals("4")) {
System.out.print("请输入新密码:");
String newpassword = scan2.next();
if (super.changeSelfInfo(newpassword)) {
System.out.println("修改成功!");
} else {
System.out.println("修改失败");
}
} else if (operator_choice.equals("5")) {
operator_isopen = false;
} else {
System.out.println("输入格式有误!请重新输入!");
}
}
}
}
Operator 类内包含上传文件的操作,也涉及了I/O流。
import java.sql.SQLException;
import java.util.Scanner;
public class Main {
@SuppressWarnings("resource")
public static void main(String[] args) {
Scanner scan1 = new Scanner(System.in);
Scanner scan2 = new Scanner(System.in);
Scanner scan3 = new Scanner(System.in);
// 控制界面开关
boolean main_isopen = true;
// 记录用户选择
String main_choice;
while (main_isopen) {
// 界面显示
System.out.println("=======欢迎进入档案系统=======");
System.out.println(" 1.登 录 ");
System.out.println(" 2.退 出 ");
System.out.println("==============================");
System.out.print("请输入选项:");
main_choice = scan1.next();
if (main_choice.equals("1")) {
System.out.print("请输入用户名:");
String input_name = scan2.next();
System.out.print("请输入密码:");
String input_password = scan3.next();
User user;
try {
user = DataProcessing.searchUser(input_name, input_password);
if (user == null) {
System.out.println("用户名与密码不符!");
} else {
user.showMenu();
}
} catch (SQLException e) {
System.out.println(e.getLocalizedMessage());
}
} else if (main_choice.equals("2")) {
try {
// 断开连接
DataProcessing.disconnectFromDB();
main_isopen = false;
} catch (SQLException e) {
System.out.println(e.getLocalizedMessage());
}
} else {
System.out.println("输入格式有误!请重新输入!");
}
}
System.out.println("系统退出,感谢使用!");
}
}
声明:本文内容来源于武汉理工大学2019-2020学年Java编程实验,仅供学习参考。如有不足错误地方,还请指出。
代码建议不要无脑抄 ,很多细节没有详细讲解,读者需自行理解。编程是实践练出来的,祝愿读者在编程之路上不断进步!