武汉理工大学-Java面向对象与多线程综合实验-(3)输入输出流

实验目标

本实验目标在实验 (2) 基础上,加入I/O流的操作,实现本地下载和上传文件的功能。可下载文件存放在磁盘 (笔者采用F盘) 的 uploadfile 文件夹,选择下载后可将指定文件下载至磁盘的 downloadfile文件夹中;选择上传则可将自己指定的文件上传至磁盘的 uploadfile 文件夹中。

同时新加入了 Doc 类,用于记录文件信息,用哈希表 docs 存储在DataProcessing类中,并加入了一系列对文件 Doc 信息增删的方法。

模块解析

首先新增加了 Doc 文件类:
武汉理工大学-Java面向对象与多线程综合实验-(3)输入输出流_第1张图片
改进后的模块结构图:
武汉理工大学-Java面向对象与多线程综合实验-(3)输入输出流_第2张图片
I/O层次结构体系:
武汉理工大学-Java面向对象与多线程综合实验-(3)输入输出流_第3张图片

源代码

本次实验代码基于实验 (2) 修改。

·DataProcessing

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()。

·Doc

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 成员。

·User

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 的输入输出流类别有很多,操作写法也不唯一,这里就不对相关知识做详细讲解了,参考一下代码相信很容易理解。

·Administrator

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("输入格式有误!请重新输入!");
			}

		}

	}
}

·Browser

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("输入格式有误!请重新输入!");
			}

		}

	}

}

·Operator

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流。

·Main

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编程实验,仅供学习参考。如有不足错误地方,还请指出。
代码建议不要无脑抄 ,很多细节没有详细讲解,读者需自行理解。编程是实践练出来的,祝愿读者在编程之路上不断进步!

你可能感兴趣的:(Java面向对象与多线程)