Java之IO,网络编程实现人机聊天对话

Java之IO,网络编程实现人机聊天对话功能

首先咱们来看一下模拟环境:
某程序员大锤有一个非常喜欢的女神,为了保留和女神的各个瞬间,某程序员大锤想把他们的聊天信息(只保留文字)都保存到自己本地系统,作为以后在一起的甜蜜回忆.
经过自己分析,他和女神聊天的信息库大致如下(这是两个文件):
=某程序员大锤常用语文件(大锤.txt):=
在么
我给你发了一个红包
好的
=女神常用语文件(女神.txt):=
正要去洗澡…
正在吃饭…
正在和朋友在一起
谢谢,那我不客气了,你早点休息
真的啊,大锤,你真好
大锤你真棒
怎么了,不开心么
…你怎么回事
…是什么意思

大致内容就是这样子了,这时候我们需要考虑的就是,如果大锤说的话不在此文件中怎么办,我这里使用的是茉莉机器人来代替女神说话
首先,前去茉莉的官网http://www.itpk.cn/来注册一个账号和密码(注:茉莉为免费机器人,本人没收茉莉一分钱,本人没收茉莉一分钱,本人没收茉莉一分钱,也不为茉莉还要其他任何一个平台代言,只是单纯的来使用一下此平台,实现自己需要的功能)

注册好,登陆后显示的界面为:在这里插入图片描述

这个时候我们记住自己的Api Key和Api Secret,在后面接入机器人来使用,下面咱们来查看接入的API在这里插入图片描述
咱们这里只是简单的实现功能,所以机器人的其他操作设置不做任何配置,使用默认即可,下面咱们一步一步的来使用IO,网络编程,实现文件读取,存储,机器人接入功能,话不多说,来操作吧:在项目下创建一个文件夹,用来存放大锤.txt和女神.txt文件

在这里插入图片描述

接着来创建聊天生成文件的类:

这里碰到了异常,不知道异常是什么的,可以去看我之前写的异常:https://blog.csdn.net/qq_45280147/article/details/106698162来简单的学习下,遇到不懂的,可以在下面加我微信进行交流

public class Chatlog{
    //定义一个全局的键盘扫描器
    static Scanner in = new Scanner(System.in);
	//main方法,因为使用到了IO,肯定会有IO异常,我这里直接选择了throws抛出,代码看着整洁,干净,在开发中,推荐使用try{}catch(Exception e){}来捕获
    public static void main(String[] args) throws IOException{
        System.out.println("===欢迎来到珍爱网交友直播现场===");
		System.out.println("===系统初始化中......");
		System.out.println("请输入您要聊天的对象:");
		String name = in.nextLine();
		//初始化字典,返回map集合
		Map<String,List<String>> map = showLog();
		System.out.println(map);
		System.out.println("聊天开始....");
		System.out.println("聊天记录即将备份到文件,请输入文件名(记得加后缀名):");
		String fileName = in.nextLine();
		String me ;
		while(true) {
			System.out.print("我:");
			me = in.nextLine();
			//调用保存日志方法
			saveLog("我",me,fileName);
			//调用获取女神回复信息的方法
			String getreply = getReply(map,me);
			//女神回复的可能没有在文件中,没有
			//然后调用HttpRequest的request方法,使用茉莉机器人来代替女神
			if(getreply == null) {
                //调用HttpRequest的request方法,返回的是String类型
				String str = HttpRequest.request(me);
				System.out.println(name+":"+str);
				saveLog(name,str,fileName);
			}else {
				System.out.println(name + ":"+ getreply);
				saveLog(name,getreply,fileName);
			}
		}
    }
}

下面就要来继续实现里面实现操作的方法了:

首先初始化系统,在原来的类里面,在main方法下面直接来写这些方法:

/**
	 * 初始化系统
	 * @throws IOException
	 */
	private static Map showLog() throws IOException {
		//初始化女神和大锤的聊天的字典
		Map<String,List<String>> map = new HashMap<String,List<String>>();
		//创建文件对象
		File chui = new File("FileTest/大锤.txt");
		File nvShen = new File("FileTest/女神.txt");
		//读取大锤文件,返回的是list集合
		List<String> chuiList = readLog(chui);
		List<String> nvList = readLog(nvShen);
//		System.out.println(chuiList);
//		System.out.println(nvList);
		//定义一个list集合,用来存放女神的对话
		List<String> values;
		//循环大锤的文件
		for(int i = 0;i<chuiList.size();i++) {
//			System.out.println(chuiList.get(i));
			//初始化女神集合
			values = new ArrayList<String>();
			//循环女神的文件,3个3个循环,正好和大锤的语录匹配上
			for(int j = i*3;j<i * 3 + 3;j++) {
//				System.out.println(nvList.get(j));
				//将女神的语录添加到集合中
				values.add(nvList.get(j));
			}
			//将他们语录添加到字典中
			map.put(chuiList.get(i), values);
		}
		
		
		return map;
	}

定义读取文件的方法,因为这些文本是一行一行的存在,所以在这里使用字符缓冲流来读取

/**
	 * 读取文件的方法
	 * @param file
	 * @return
	 * @throws IOException
	 */
	private static List readLog(File file) throws IOException {
		//创建list集合,将读取到的内容存入集合中
		List<String> list = new ArrayList<String>();
		//定义字符缓冲输入流
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
		String line;
		//为null结束循环
		while((line = br.readLine())!=null) {
			//添加到集合中
			list.add(line);
		}
		//关流
		if(br != null)br.close();
		return list;
	}
}

然后来获取女神的回复:

/**
	 * 获取回复信息
	 * @param me 
	 * @param map 
	 */
	private static String  getReply(Map<String, List<String>> map, String me) {
		//定义一个集合,用来接收循环后的女神对话
		List<String> value = null;
		//将map集合转换为set集合
		Set<String> set = map.keySet();
		//使用for循环,进行遍历
		for(Object obj : set) {
//			System.out.println(obj+" "+map.get(obj));
			//如果输入的内容和集合的中键包含,将保存到value集合中
			if(me.contains(obj.toString())) {
				value = map.get(obj);
				break;
			}
		}
		//如果输入的不在范围内,返回null,否则的话,会报空指针异常,在这里也方便上面用来判断是否有女神的回复
		if(value == null) {
			return null;
		}
		//随机数
		Random r = new Random();
		//随机获取女神的对话
		me = value.get(r.nextInt(3));
		return me;
	}

最后保存聊天记录:

/**
	 * 保存聊天记录
	 * @param name
	 * @param getreply
	 * @throws IOException 
	 */
	private static void saveLog(String name, String getreply,String fileName) throws IOException {
		//创建文件对象
		File file = new File(fileName);
		//判断这个文件是否存在,不存在则创建
		if(!file.exists()) {
			file.createNewFile();
		}
		//格式化时间
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String date = sdf.format(new Date());
		//调用字符缓冲输出流,后面加true代表可以追加,可以在文件下面写入
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName,true)));
		//写入文件
		bw.write(date+"-"+name+":"+getreply);
		//换行
		bw.newLine();
		//关流
		if(bw!=null) bw.close();
	}

与女神的基本对话,就这么多,下面就来写与女神对话文件没有时候的操作,也就是接入机器人,创建http类

/*
 * 向机器人发送请求和解析机器人的相应
 * */
public class HttpRequest {
	//设置相关常量
	//api_key,我这里一部分用*来代替了,大家修改成自己的
	public static final String API_KEY = "4cf4******a9f73de******26359e78e";
	//API_PASSWORD
	public static final String API_SECRET = "totc******uo";
	//基础路径
	public static final String BASE_PATH = "http://i.itpk.cn/api.php?";
	//发送请求的方法
	public static String request(String msg) {
		//将消息字符集转码(utf-8 gbk iso-8859-1(欧洲编码 不支持中文))
		try {
			msg = URLEncoder.encode(msg,"utf-8");
			//拼接请求路径
			String path =  BASE_PATH + "question=" + msg + "&api_key=" + API_KEY + "&api_secret=" + API_SECRET;
			//将请求包装成一个对象
			URL url = new URL(path);
			//打开连接
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			//设置请求方式
			conn.setRequestMethod("GET");
			//发送请求并获取相应参数(200:成功 404:路径 not found 500:server err)
			int code = conn.getResponseCode();
//			System.out.println(code);
			if(code == 200) {
				//请求成功,接受机器人的消息
				//获取连接对象的输入流
				InputStream is = conn.getInputStream();
				//将字节流转换成字符流
				InputStreamReader isr = new InputStreamReader(is,"utf-8");
				//字符缓冲
				BufferedReader br = new BufferedReader(isr);
				//读取消息,声明一个字符串变量,用来保存每次读取的数据
				String msg2= "";
				StringBuffer string = new StringBuffer();//最终的消息
				//循环读取消息
				while((msg2 = br.readLine())!= null) {
					string.append(msg2+"\n");
				}
				//返回字符串的缓冲区的内容
				return string.toString().substring(1, string.length()-1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
		
	}
}

来看运行效果图:

在这里插入图片描述

在这里插入图片描述

好了,本期异常就说到这里了,如果对异常或者其他有不懂的地方,欢迎前来加我微信进行探讨
看完别忘记点赞哦
在这里插入图片描述

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值