用户点击取消按钮时终止独立线程中运行的文件传输任务
实现文件传输的取消终止方案
要解决用户取消API调用后后台仍继续传输文件的问题,核心是通过线程中断机制配合IO资源的及时清理来实现终止,具体步骤如下:
1. 在API取消触发时发送中断信号
当用户发起取消操作(比如前端取消请求、HTTP连接断开),调用Future的cancel(true)方法,给后台执行传输任务的线程发送中断信号:
// 示例:在取消逻辑中执行 if (future != null && !future.isDone()) { future.cancel(true); }
2. 在传输方法中响应中断并清理资源
修改transferFileMethod,在关键节点检查线程中断状态,同时处理IO操作的中断异常,及时关闭所有打开的资源:
Map<String, Object> transferFileMethod(SomeParameters someparameters) throws IOException { HttpURLConnection urlConnection = null; InputStream inputStream = null; try { urlConnection = (HttpURLConnection) someparameters.getRequestUrl().openConnection(); inputStream = urlConnection.getInputStream(); try (BufferedOutputStream fileOutputStream = new BufferedOutputStream( new FileOutputStream(someparameters.getFilePath(), true))) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = inputStream.read(buffer, 0, 4096)) != -1) { // 检查线程是否被中断,触发则终止传输 if (Thread.currentThread().isInterrupted()) { throw new InterruptedException("文件传输被用户取消"); } fileOutputStream.write(buffer, 0, bytesRead); } } } catch (InterruptedException e) { // 捕获中断信号,强制断开连接并清理资源 Thread.currentThread().interrupt(); // 保留中断状态,供上层处理 if (urlConnection != null) { urlConnection.disconnect(); } // 可选:删除未完成的目标文件 // new File(someparameters.getFilePath()).delete(); throw new IOException("传输已取消", e); } catch (IOException e) { // 处理其他IO异常,确保连接断开 if (urlConnection != null) { urlConnection.disconnect(); } throw e; } finally { // 确保输入流被关闭 if (inputStream != null) { try { inputStream.close(); } catch (IOException ignored) {} } } return Map.of("status", "success"); }
关键说明
future.cancel(true)会触发线程的中断状态,Thread.currentThread().isInterrupted()用于检测该状态,主动抛出异常终止循环。- 捕获
InterruptedException后,必须调用Thread.currentThread().interrupt()重置中断状态,避免上层代码忽略中断信号。 - 无论传输成功还是中断,都要确保
HttpURLConnection被断开、流被关闭,防止资源泄漏。 - 若需要保证文件完整性,可在中断时删除未完成的目标文件。
内容的提问来源于stack exchange,提问作者Amit J.
相关产品推荐
相关产品推荐

