我正在尝试同时将一些文件发送到 rest api。试图实施这个答案
public class UploadThread implements Runnable {
private File file;
public UploadThread(File file) {
this.file = file;
}
@Override
public void run() {
try {
String url = // api url
URL server = new URL(url);
HttpURLConnection connection = (HttpURLConnection) server.openConnection();
// setting request properties here
connection.connect();
OutputStream out = connection.getOutputStream();
FileInputStream in = new FileInputStream(file);
try {
// write to outputstream
} catch (Exception ex) {
ex.printStackTrace();
} finally {
out.close();
in.close();
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
// error handling here
}
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class UploadTest {
public static void main(String[] args) throws Exception {
List<File> files = Files.walk(Paths.get("/home/random"))
.filter(Files::isRegularFile)
.map(Path::toFile)
.collect(Collectors.toList());
ExecutorService executorService = Executors.newFixedThreadPool(5);
for(File file : files) {
Runnable worker = new UploadThread(file);
executorService.execute(worker);
}
executorService.shutdown();
while(!executorService.isTerminated()) {
//
}
System.out.println("upload finished....");
}
}
我在random
目录中有 10 个文件。
当我执行这个时,第一个文件的发送次数与我在Executors.newFixedThreadPool()
方法中分配的线程数完全相同。
如果我分配 5 个线程,则第一个文件(每次执行时不同)将发送 5 次,而其余文件仅发送一次!对于 10 个线程,发送 10 次!
为什么只有一个文件被多次发送,而其余的则不是?我在代码中做错了什么?
编辑:我将文件发送到的 api 正在使用Jersey
on Tomcat 8
。以下是文件的处理方式。
在资源上
@Path("file")
public class MyResource {
private StorageManager storageManager;
public MyResource() {
this.storageManager = new StorageManager();
}
@GET
@Path("upload")
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
public Response upload(InputStream inputStream) {
return this.storageManager.upload(inputStream);
}
}
和StorageManager
类
public class StorageManager {
public Response upload(InputStream inputStream) {
// handling file upload here
// this method is called 5 or 10 times for one file
// return some response
}
}
对于单个文件,这工作得很好。我已经使用 REST 客户端上传了数百个文件,并且每次都有效。但是对于并发请求,此upload()
方法会为任何一个文件(第一个)调用多次。
试过你的代码,似乎工作正常。顺便说一句,没有必要将 a 映射Path
到 aFile
因为Files.copy
您可以轻松地将 a 的内容复制Path
到 an OutputStream
。
public class UploadThread implements Runnable {
private Path file;
public UploadThread(Path file) {
this.file = Objects.requireNonNull(file);
}
@Override
public void run() {
try {
String url = // api url
URL server = new URL(url);
HttpURLConnection connection = (HttpURLConnection) server.openConnection();
// setting request properties here
connection.connect();
try (OutputStream out = connection.getOutputStream()) {
Files.copy(file, out);
} finally {
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
// error handling here
}
connection.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
您还可以放弃for
和 'while' 循环:
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(5);
Files.walk(Paths.get("/home/random"))
.filter(Files::isRegularFile)
.map(UploadThread::new)
.forEach(executorService::execute);
executorService.shutdown();
System.out.println("upload finished....");
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句