2018-03-04

package org.ddl.chat;

import java.io.*;
import java.util.ResourceBundle;
import java.util.Scanner;

/**
 * 这是一个读取聊天记录的线程类
 */
public class MyRunner implements Runnable {

    //经常变动 或 重复使用的数据,我们将其声明为类变量
    private boolean isUpdate; //文件更新标识
    private long lastTime = 0;//文件更新时间
    private String fileName = "D:/chat.log"; //默认文件名,也可通过配置文件去改变
    private File chatFile;  //聊天文件
    private InputStreamReader read;
    private BufferedReader bufferedReader;
    private String currentName;//当前用户

    //实例创建时的的构造函数, 创建该实例时,将当前的用户名传入
    public MyRunner(String name) {
        this.currentName = name;//设置当前用户
        try {
            //设置当前类的 聊天文件,及读取文件的read.?为什么要在构造函数去声明这些东西,而不是在使用时?
            ResourceBundle bundle = ResourceBundle.getBundle("pro");
            fileName = bundle.containsKey("CHAT_FILE") ? bundle.getString("CHAT_FILE") : fileName;
            chatFile = new File(fileName);
            if (!chatFile.exists()) {
                chatFile.createNewFile();
            }
            read = new InputStreamReader(
                    new FileInputStream(chatFile), "GBK");//考虑到编码格式
            bufferedReader = new BufferedReader(read);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

    }
    //这里的调用是 创建一个线程 start后,线程会在后台去执行run方法,而不是主线程中?什么是主线程,在main的执行过程都叫主线程。。
    @Override
    public void run() {
        try {
            while (true) { //循环检测
                if (isChange()) {  //调用函数,文件是否有更新
                    readFile();  //有更新就去读文件
                }
                Thread.sleep(1000);//检测一次休息0.1秒
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    //读取文件
    public void readFile() {
        try {
            String lineTxt = null;
            while ((lineTxt = bufferedReader.readLine()) != null) {
                if (!lineTxt.startsWith(this.currentName)) {
                    System.out.println(lineTxt);
                }
            }
        } catch (Exception e) {
            System.out.println("读取文件内容出错");
            e.printStackTrace();
        }
    }


    //判断文件有没有更新的方法
    public boolean isChange() {
        long lastTime = chatFile.lastModified(); //局部变量,与对象全局变量一样时,注意是如何使用
        isUpdate = this.lastTime != lastTime;
        this.lastTime = lastTime;
        return isUpdate;
    }

    //快速测试类main
    public static void main(String[] avgr){
        Scanner scanner = new Scanner(System.in);
        System.out.println("Pls input english name:");
        String name = scanner.next() + ":"; //进来系统后,要求输入用户名
        //new Thread()是java 创建线程的 语法,需要传入,一个你自己实现的的Thread
        MyRunner runner=new MyRunner(name); //将自己定义的线程实现类创建
        Thread thread=new Thread(runner);   //将扔进java的线程
        thread.start(); //启动线程
//        (new Thread(new MyRunner(name))).start(); //上面的三个步骤一行来写,通常在你知道这个对象只会声明这一次时,才敢这么写!!!(啥叫只声明一次?) 比如,我们的线程,启起来了,就不用动了!(也就是常说的,这个对象创建后,后面不需要引用他,就没有必要去声明一个变量)

        //下面是针消息发送时,写文件!(整个的过程是 用户写消息到文件,同时,用户通过线程去监听有没有新消息,有的话就把新的消息打印出来).
        File file = new File("d:/chat.log");
        FileWriter fw;
        PrintWriter printStream;
        try {
            while (true) {
                fw = new FileWriter(file, true);
                printStream = new PrintWriter(fw);
                printStream.println(name + scanner.next());
                printStream.close();
                Thread.sleep(500);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用以下代码将给定的列表转换成一个 Pandas 数据框(DataFrame): ```python import pandas as pd # 给定的列表数据 data = [['日期', '2018-01-03', -1.172468, '2018-01-04', -0.258565, '2018-01-05', 0.163079, '2018-01-08', -1.179654, '2018-01-09', 0.411397, '2022-12-26', -0.784676, '2022-12-27', 1.262722, '2022-12-28', 0.104694, '2022-12-29', -0.408606, '2022-12-30', 0.484443], ['日期', '2018-01-03', -0.329916, '2018-01-04', -0.012197, '2018-01-05', -0.615016, '2018-01-08', -1.149181, '2018-01-09', -0.173742, '2022-12-26', -0.177332, '2022-12-27', 1.786322, '2022-12-28', 1.108457, '2022-12-29', -0.693480, '2022-12-30', 0.333768], ['日期', '2018-01-03', -0.295204]] # 将列表转换成数据框 df = pd.DataFrame(data) # 设置列名 df.columns = ['col' + str(i) for i in range(df.shape[1])] # 将第一列作为行索引 df = df.set_index('col0') # 将奇数列作为日期列,偶数列作为数值列 df_dates = df.iloc[:, ::2] df_values = df.iloc[:, 1::2] df_dates.columns = range(df_dates.shape[1]) df_values.columns = range(df_values.shape[1]) # 将日期列和数值列合并成一个数据框 df = pd.concat([df_dates.stack(), df_values.stack()], axis=1) df.columns = ['日期', '数值'] # 将日期列转换成日期类型 df['日期'] = pd.to_datetime(df['日期']) ``` 注意:给定的列表中有多个子列表,每个子列表包含了日期和数值数据。我们需要将这些子列表转换成一个 Pandas 数据框,并将日期列和数值列拆分成两个数据框,然后再将它们合并成一个数据框。最后,我们还需要将日期列转换成 Pandas 中的日期类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值