项目的小结

项目场景:

作业的发布,打回 。 学生端做作业

由作业的state来确定作业是否上交,批改,打回作业。

实体类的建立,还有各种成员变量的设计要满足需求


问题描述

问题:

在进行上传作业后,老师端批改作业,并作出评论,这所有的信息我全部都写在一张表里面,导致自己的思维有点混乱。这里应该把老师的批改单独建立一张表,进行存储数据。

这里建立实体类就是传递数据,客户端与服务端的交互数据传值就比乱,


原因分析:

提示:因为状态不同导致,有些传值就只有一些有效值存在,其它值没有传递,但是有时候,在后面又会再次使用

 比如前面查询时只有id,而后面需要一个name,这时就需要单独又要去请求一遍

解决方案:

实体类:作业:进行找值,还有进行赋值,传值,就比较方便

package com.test.po;

import java.io.Serializable;
import java.time.LocalDateTime;

public class MyWork implements Serializable {
    private int id;
    private int classId;
    private int student_id;
    private int state;      //1:已提交  2:未批改 3:已批改 4:已打回
    private String answer;
    private String question;
    private LocalDateTime start_time;
    private LocalDateTime end_time;
    private int score;
    private String StudentName;
    private String teacher_reply;
    private String workName;

    public String getWorkName() {
        return workName;
    }

    public void setWorkName(String workName) {
        this.workName = workName;
    }

    public String getTeacher_reply() {
        return teacher_reply;
    }

    public void setTeacher_reply(String teacher_reply) {
        this.teacher_reply = teacher_reply;
    }

    public LocalDateTime getStart_time() {
        return start_time;
    }

    public void setStart_time(LocalDateTime start_time) {
        this.start_time = start_time;
    }



    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getStudentName() {
        return StudentName;
    }

    public void setStudentName(String studentName) {
        StudentName = studentName;
    }
    public int getClassId() {
        return classId;
    }

    public void setClassId(int classId) {
        this.classId = classId;
    }

    public int getStudent_id() {
        return student_id;
    }

    public void setStudent_id(int student_id) {
        this.student_id = student_id;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public String getAnswer() {
        return answer;
    }

    public void setAnswer(String answer) {
        this.answer = answer;
    }

    public String getQuestion() {
        return question;
    }

    public void setQuestion(String question) {
        this.question = question;
    }

    public LocalDateTime getEnd_time() {
        return end_time;
    }

    public void setEnd_time(LocalDateTime end_time) {
        this.end_time = end_time;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }
}

班级资源的下载

当学生点击下载后,弹出选择文件地址,因为进行下载文件,需要文件分片下载,并且下载文件时需要单独的线程,否则会堵塞。因为采用的长连接,最方便的就是采用一个新的socket。

package com.test.controller;

import com.test.Util.SocketUtil;
import com.test.common.Message;
import com.test.common.MessageType;
import com.test.po.MyFile;
import com.test.po.MyLargerFile;
import javafx.application.Platform;

import java.io.*;
import java.net.Socket;
import java.nio.file.Files;

public class MyFileRunnable implements Runnable {
    private Socket socket;
    private File file;
    public int state;
    public int flag = 0;

    public MyFileRunnable(Socket socket, File file) {
        this.socket = socket;
        this.file = file;
    }

    @Override
    public void run() {
        // 假设分片存储目录
        File storageDirectory = new File(file.getParent(), "chunks");

        while (!socket.isClosed()) {
            try {
                Message responseMessage = SocketUtil.getSocketUtil().getMessage(socket);
                switch (responseMessage.getMessageType()) {
                    case MessageType.stu_download_file_start -> {
                        MyLargerFile myLargerFile = (MyLargerFile) responseMessage.getData();
                        MyFile myFile = myLargerFile.getMyFile();
                        // 假设分片信息存储在MyFile中,包括分片总数和当前分片序号
                        int totalChunks = myLargerFile.getTotalSlices();
                        int chunkNumber = myLargerFile.getState(); // 假设这个方法存在

                        // 创建分片存储目录
                        if (!storageDirectory.exists()) {
                            storageDirectory.mkdirs();
                        }

                        // 存储分片
                        File chunkFile = new File(storageDirectory, "chunk_" + chunkNumber);
                        myFile.writeFileData(chunkFile);
                        //进行更新ui

                        Platform.runLater(()->{
                            ControllerManager.stuClassIfoController.stringStuIfoPaneControllerHashMap.get(myLargerFile.getMd5()).update(myLargerFile);

                        });

                        // 检查是否所有分片都已下载
                        if (areAllChunksDownloaded(storageDirectory, totalChunks)) {
                            // 合并分片
                            mergeChunks(storageDirectory, file, totalChunks);
                            System.out.println("文件下载完成");
                            return;
                        }



                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                return;
            }
        }
    }

    private boolean areAllChunksDownloaded(File directory, int totalChunks) {
        for (int i = 1; i <= totalChunks; i++) {
            File chunkFile = new File(directory, "chunk_" + i);
            if (!chunkFile.exists()) {
                return false;
            }
        }
        return true;
    }

    private void mergeChunks(File directory, File outputFile, int totalChunks) throws IOException {
        try (FileOutputStream fos = new FileOutputStream(outputFile, true);
             BufferedOutputStream mergingStream = new BufferedOutputStream(fos)) {
            for (int i = 1; i <= totalChunks; i++) {
                File chunkFile = new File(directory, "chunk_" + i);
                Files.copy(chunkFile.toPath(), mergingStream);
                // 删除分片文件,如果需要的话
//                chunkFile.delete();
            }
        }
    }
}

 这个先进行文件分片的下载,当下载完成之后,再进行执行合并文件。并关闭这个线程。

服务端进行文件上传我也采用了多线程进行执行上传文件:

 case MessageType.stu_download_file -> {
                        MyLargerFile myLargerFile = (MyLargerFile) requestMessage.getData();
                        String md5 = myLargerFile.getMd5();
                        MyLargerFile my= MyFileDAO.queryFile(md5);
                        String dir = my.getPath();

                        File[] files = new File(dir).listFiles();
                        if (files == null) {
                            System.out.println("文件目录不存在");
                            return;
                        }
                        int len = files.length;

                        Arrays.sort(files, (f1, f2) -> {
                            // 分割文件名,获取分片编号部分
                            String[] parts1 = f1.getName().split("\\.part");
                            String[] parts2 = f2.getName().split("\\.part");

                            // 提取并解析分片编号
                            int part1 = Integer.parseInt(parts1[1]);
                            int part2 = Integer.parseInt(parts2[1]);

                            // 比较分片编号
                            return Integer.compare(part1, part2);
                        });

                        new Thread(()->{
                            int index = 1;
                            for (File file : files) {
                                MyFile myFile = new MyFile();
                                myFile.readFileData(file);

                                MyLargerFile myLargerFile1 = new MyLargerFile();
                                myLargerFile1.setMyFile(myFile);

                                myLargerFile1.setState(index);
                                myLargerFile1.setTotalSlices(len);
                                myLargerFile1.setMd5(md5);


                                Message message = new Message();
                                message.setData(myLargerFile1);
                                message.setMessageType(MessageType.stu_download_file_start);
                                try {
                                    SocketUtil.getSocketUtil().sendMessage(socket,message);
                                } catch (IOException e) {
                                    throw new RuntimeException(e);
                                }
                                index++;

                            }

                        }).start();

                    }
 

在这种情况下,进行传递文件数据。然后读写文件。

 

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值