do{ sb.append(s); }while(sb.toString().equals("end"));
时间: 2024-04-25 08:22:48 浏览: 12
这是一个简单的do-while循环,它会一直执行代码块直到满足循环条件不成立为止。在这个例子中,代码块会将字符串s附加到StringBuilder对象sb上,并且在每次循环结束时将sb转换为字符串,然后检查是否等于"end"。如果等于"end",则循环结束;如果不等于"end",则继续执行循环。
注意:这段代码可能会导致无限循环,因为循环条件取决于sb的内容是否等于"end",而代码块中并没有改变sb的内容。如果需要退出循环,需要在循环体内修改sb的内容,使其不再等于"end"。
相关问题
写一下springmvc + vue的大文件分片上传代码。要求:1.前端加入MD5;2.用elementui
好的,以下是一个示例代码,使用SpringMVC和Vue实现大文件分片上传,同时前端加入MD5校验,使用ElementUI实现进度条显示。
前端代码:
```vue
<template>
<div>
<el-upload
class="upload-demo"
action="/upload"
:before-upload="beforeUpload"
:on-progress="onProgress"
:on-success="onSuccess"
:file-list="fileList">
<el-button type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传不超过 200MB 的文件</div>
</el-upload>
<el-progress :percentage="percentage" :stroke-width="30" :text-inside="true"></el-progress>
</div>
</template>
<script>
import SparkMD5 from 'spark-md5'
export default {
data() {
return {
fileList: [],
percentage: 0,
}
},
methods: {
beforeUpload(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
const chunkSize = 2 * 1024 * 1024 // 分片大小为2MB
const chunks = Math.ceil(file.size / chunkSize)
const spark = new SparkMD5.ArrayBuffer()
let currentChunk = 0
reader.onload = e => {
spark.append(e.target.result)
currentChunk++
if (currentChunk < chunks) {
loadNext()
} else {
file.md5 = spark.end()
resolve(file)
}
}
reader.onerror = () => {
reject('读取文件出错')
}
function loadNext() {
const start = currentChunk * chunkSize
const end = Math.min(start + chunkSize, file.size)
reader.readAsArrayBuffer(file.slice(start, end))
}
loadNext()
})
},
onProgress(e) {
this.percentage = e.percent
},
onSuccess(response, file) {
this.percentage = 0
this.fileList = []
this.$message.success('上传成功')
},
},
}
</script>
```
在这个示例代码中,我们使用了SparkMD5库来计算文件的MD5,同时在`beforeUpload`方法中,将文件分成多个2MB的分片进行上传,以实现大文件分片上传和MD5校验。在上传过程中,我们使用了ElementUI的进度条组件来显示上传进度。
后端代码:
```java
@Controller
public class UploadController {
private static final String UPLOAD_DIR = "/tmp/uploads/";
private static final int CHUNK_SIZE = 2 * 1024 * 1024;
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<?> upload(@RequestParam("file") MultipartFile file, @RequestParam("md5") String md5,
@RequestParam(value = "chunk", required = false, defaultValue = "0") int chunk,
@RequestParam(value = "chunks", required = false, defaultValue = "1") int chunks) throws IOException {
String fileName = file.getOriginalFilename();
String filePath = UPLOAD_DIR + fileName;
if (chunk == 0) {
// 如果是第一个分片,检查文件是否存在,如果存在则直接返回
File f = new File(filePath);
if (f.exists()) {
return ResponseEntity.status(HttpStatus.OK).build();
}
} else {
// 如果不是第一个分片,检查文件是否存在,如果不存在则返回错误
File f = new File(filePath);
if (!f.exists()) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("文件不存在");
}
}
if (chunk == 0) {
// 如果是第一个分片,创建文件
File f = new File(filePath);
if (!f.getParentFile().exists()) {
f.getParentFile().mkdirs();
}
f.createNewFile();
}
// 写入分片数据
RandomAccessFile raf = new RandomAccessFile(filePath, "rw");
raf.seek(chunk * CHUNK_SIZE);
raf.write(file.getBytes());
raf.close();
if (chunk == chunks - 1) {
// 如果是最后一个分片,检查文件MD5值是否正确,如果正确则合并文件
String fileMd5 = getFileMd5(filePath);
if (!fileMd5.equals(md5)) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("文件MD5值不正确");
}
mergeFileChunks(filePath, chunks);
}
return ResponseEntity.status(HttpStatus.OK).build();
}
private String getFileMd5(String filePath) throws IOException {
InputStream fis = new FileInputStream(filePath);
byte[] buffer = new byte[1024];
int numRead;
MessageDigest md5;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
return null;
}
do {
numRead = fis.read(buffer);
if (numRead > 0) {
md5.update(buffer, 0, numRead);
}
} while (numRead != -1);
fis.close();
byte[] md5Bytes = md5.digest();
StringBuilder sb = new StringBuilder();
for (byte b : md5Bytes) {
sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
private void mergeFileChunks(String filePath, int chunks) throws IOException {
File f = new File(filePath);
FileOutputStream fos = new FileOutputStream(f, true);
byte[] buffer = new byte[1024];
for (int i = 0; i < chunks; i++) {
String chunkFilePath = filePath + "." + i;
File chunk = new File(chunkFilePath);
FileInputStream fis = new FileInputStream(chunk);
int numRead;
while ((numRead = fis.read(buffer)) > 0) {
fos.write(buffer, 0, numRead);
}
fis.close();
chunk.delete();
}
fos.close();
}
}
```
在后端代码中,我们使用了`RandomAccessFile`来实现文件的分片写入和合并,同时在文件合并前使用了`getFileMd5`方法来检查文件的MD5值是否正确。
最后,我们还需要在SpringMVC的配置文件中添加以下配置,以支持大文件上传:
```xml
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="209715200" />
<property name="maxInMemorySize" value="4096" />
</bean>
```
修正以下代码:import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Sever { // 保存所有用户的用户名和密码 private static Map<String, String> userMap = new HashMap<>(); // 指定的目录 private static File rootDir = null; // 保存所有登录的用户信息 private static Map<String, String> loginInfo = new HashMap<>(); public static void main(String[] args) throws Exception { // 从配置文件中读取用户信息和目录信息 BufferedReader reader = new BufferedReader(new FileReader("config.txt")); String line = null; while ((line = reader.readLine()) != null) { if (line.startsWith("user:")) { String[] user = line.split(":"); userMap.put(user[1], user[2]); } if (line.startsWith("dir:")) { String[] dir = line.split(":"); rootDir = new File(dir[1]); } } reader.close(); // 启动服务器 ServerSocket serverSocket = new ServerSocket(8000); int count = 0; System.out.println("服务器启动成功!"); while (true) { // 监听客户端连接 Socket socket = serverSocket.accept(); count++; System.out.println("第" + count + "个客户端连接成功!"); // 处理客户端请求 new Thread(new ServerThread(socket)).start();
以下是代码修正:
```java
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Server {
// 保存所有用户的用户名和密码
private static Map<String, String> userMap = new HashMap<>();
// 指定的目录
private static File rootDir = null;
// 保存所有登录的用户信息
private static Map<String, String> loginInfo = new HashMap<>();
public static void main(String[] args) throws Exception {
// 从配置文件中读取用户信息和目录信息
BufferedReader reader = new BufferedReader(new FileReader("config.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
if (line.startsWith("user:")) {
String[] user = line.split(":");
userMap.put(user[1], user[2]);
}
if (line.startsWith("dir:")) {
String[] dir = line.split(":");
rootDir = new File(dir[1]);
}
}
reader.close();
// 启动服务器
ServerSocket serverSocket = new ServerSocket(8000);
int count = 0;
System.out.println("服务器启动成功!");
while (true) {
// 监听客户端连接
Socket socket = serverSocket.accept();
count++;
System.out.println("第" + count + "个客户端连接成功!");
// 处理客户端请求
new Thread(new ServerThread(socket, userMap, rootDir, loginInfo)).start();
}
}
}
class ServerThread implements Runnable {
private Socket socket;
private Map<String, String> userMap;
private File rootDir;
private Map<String, String> loginInfo;
public ServerThread(Socket socket, Map<String, String> userMap, File rootDir, Map<String, String> loginInfo) {
this.socket = socket;
this.userMap = userMap;
this.rootDir = rootDir;
this.loginInfo = loginInfo;
}
@Override
public void run() {
try {
// 获取输入输出流
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
// 接收客户端请求
String request = reader.readLine();
if (request == null) {
return;
}
System.out.println("客户端请求:" + request);
// 登录处理
if (request.startsWith("login:")) {
String[] login = request.split(":");
String username = login[1];
String password = login[2];
if (userMap.containsKey(username) && userMap.get(username).equals(password)) {
loginInfo.put(socket.getInetAddress().getHostAddress(), username);
writer.println("login success");
} else {
writer.println("login fail");
}
}
// 列出目录内容处理
else if (request.equals("list")) {
String username = loginInfo.get(socket.getInetAddress().getHostAddress());
if (username == null) {
writer.println("not login");
} else {
File[] files = rootDir.listFiles();
StringBuilder sb = new StringBuilder();
sb.append("total ").append(files.length).append("\n");
for (File file : files) {
sb.append(file.getName()).append("\n");
}
writer.println(sb.toString());
}
}
// 下载文件处理
else if (request.startsWith("get:")) {
String filename = request.substring(4);
String username = loginInfo.get(socket.getInetAddress().getHostAddress());
if (username == null) {
writer.println("not login");
} else {
File file = new File(rootDir, filename);
if (!file.exists()) {
writer.println("file not exist");
} else if (!file.isFile()) {
writer.println("not a file");
} else {
writer.println("file start");
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
socket.getOutputStream().write(buffer, 0, len);
}
fis.close();
socket.getOutputStream().flush();
writer.println("file end");
}
}
}
// 未知请求处理
else {
writer.println("unknown request");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
```
在主程序中,将 ServerThread 构造函数中需要的参数传入,确保 ServerThread 中可以使用这些参数。
在 ServerThread 中,将所有需要使用的变量都作为成员变量传入构造函数中,确保可以在 run 方法中使用。
另外,在处理下载文件请求时,需要将文件内容以字节流的形式写入输出流,否则客户端无法正确接收到文件。