已实现的功能点:
存在的问题:
1.没有实现有含金量的创新功能点
2.太过于依赖工具,不喜欢自己看文章总结对知其然而不知其所以然,自己的理解比较少,懒于去思考
3.太过于依赖他人,自己的想法有点少,遇到bug会有退缩,不继续去探究,而去寻求更简单的方式
4.不够细心,总是出现一些非常小的bug
5.项目结构的理解还不够深刻,积极性不够,在后面也有些松懈
6.页面实现的太丑
学习到的东西:
msq基础 jdbc 的基本语句(后续还需要继续巩固),实现一个项目的基本结构(前后端的区别、长连接的实现),javafx的基本使用,debug的能力
需要做的事情:
1.再花一周时间去实现一个创新功能点,比如发送语音和语音通话,然后修改部分bug,优化界面,或者实现我想写却没有完成的地方,例如好友分组,黑名单
2.在完成上述要求后巩固mysql基础,刷部分算法题
3.继续学习下个项目所需要用到的东西
文件分片:
作用:
1.提升传输效率:通过传输多个分片,显著减少大文件传输时间(但是当文件比较小时,反而会加长文件传输的时间),充分利用网络资源
2.优化资源管理:支持对单个分片进行加密、压缩、或备份,降低管理复杂度
运用场景:(在我现在的水平能够用上和理解的基础上)
1.大文件传输与云存储
2.流媒体与在线播放
3.即使通讯与文件共享
实现过程:
1.在消息类中定义总分片个数大小和现在所传递的分片个数大小
public class Message implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private Long from_id;
private String send_time;
private int msg_type;
private String content;
private Long to_id;
private user u;
private int totalChunks;
private int currentChunk;
2.计算分片大小
分片个数大小=文件长度/分片大小
// 文件信息
String fileName = selectedFile.getName();
long fileSize = selectedFile.length();
Path filePath = selectedFile.toPath();
// 分片参数配置
final int CHUNK_SIZE = 1024 * 1024; // 1MB
int totalChunks = (int) Math.ceil((double) fileSize / CHUNK_SIZE);
3.发送分片
不断循环发送文件片数
// 分片发送
try (InputStream inputStream = new FileInputStream(filePath.toFile())) {
byte[] buffer = new byte[CHUNK_SIZE];
int bytesRead;
int chunkIndex = 0;
while ((bytesRead = inputStream.read(buffer)) > 0) {
Message chunkMsg = new Message();
chunkMsg.setMsg_type(4);
chunkMsg.setFrom_id(u.getId());
chunkMsg.setTo_id(f.getId());
chunkMsg.setIsperson(1);
chunkMsg.setCurrentChunk(chunkIndex);
chunkMsg.setTotalChunks(totalChunks);
chunkMsg.setContent(fileName);
chunkMsg.setFilesize(Long.toString(fileSize));
chunkMsg.setPicture(Arrays.copyOf(buffer, bytesRead));
oos.writeObject(markTool.sendMessage);
oos.writeObject(chunkMsg);
oos.flush();
chunkIndex++;
updateProgress(chunkIndex, totalChunks);
}
}
showRight("文件发送成功: ",fileName);
} catch (IOException e) {
showAlert("错误", "文件发送失败");
e.printStackTrace();
}
4.将分片文件写入临时目录,并且判断是否已经将所有分片进行发送,如果是则合并分片,并且删除临时分片,否则继续接收
Path tempDir = Paths.get(basePath, "temp", sanitizedFileName + "_temp");
try {
// 确保临时目录存在
if (!Files.exists(tempDir)) {
Files.createDirectories(tempDir);
}
// 写入分片(强制同步到磁盘)
Path chunkFile = tempDir.resolve(currentChunk + ".part");
Files.write(chunkFile, fileBytes, StandardOpenOption.CREATE, StandardOpenOption.SYNC);
} catch (IOException e) {
throw new IOException("分片写入失败: " + e);
}
if (currentChunk == totalChunks - 1) {
try {
// 合并前检查所有分片是否存在
for (int i = 0; i < totalChunks; i++) {
Path partFile = tempDir.resolve(i + ".part");
if (!Files.exists(partFile)) {
throw new IOException("缺失分片: " + partFile);
}
}
// 合并文件
Path finalPath = Paths.get(basePath, "uploads", UUID.randomUUID() + "_" + sanitizedFileName);
Path uploadsDir = Paths.get(basePath, "uploads");
if (!Files.exists(uploadsDir)) {
Files.createDirectories(uploadsDir);
}
try (OutputStream os = Files.newOutputStream(finalPath)) {
for (int i = 0; i < totalChunks; i++) {
Path partFile = tempDir.resolve(i + ".part");
Files.copy(partFile, os);
Files.delete(partFile); // 删除分片
}