项目的小结

项目场景:

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

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

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


问题描述

问题:

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

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

原因分析:

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

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

解决方案:

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

java 复制代码
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();

}

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

相关推荐
烬奇小云3 小时前
认识一下Unicorn
android·python·安全·系统安全
顾北川_野15 小时前
Android 进入浏览器下载应用,下载的是bin文件无法安装,应为apk文件
android
CYRUS STUDIO15 小时前
Android 下内联汇编,Android Studio 汇编开发
android·汇编·arm开发·android studio·arm
右手吉他15 小时前
Android ANR分析总结
android
PenguinLetsGo17 小时前
关于 Android15 GKI2407R40 导致梆梆加固软件崩溃
android·linux
杨武博19 小时前
音频格式转换
android·音视频
音视频牛哥21 小时前
Android音视频直播低延迟探究之:WLAN低延迟模式
android·音视频·实时音视频·大牛直播sdk·rtsp播放器·rtmp播放器·android rtmp
ChangYan.21 小时前
CondaError: Run ‘conda init‘ before ‘conda activate‘解决办法
android·conda
二流小码农21 小时前
鸿蒙开发:ForEach中为什么键值生成函数很重要
android·ios·harmonyos
夏非夏1 天前
Android 生成并加载PDF文件
android