- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试使用多线程从远程服务器下载多个文件。但是,当我使用多个线程时,我得到了
java.lang.IOException : Pipes closed.
当我只使用一个线程时,相同的代码工作正常。
难道不能使用 JSch 从同一个远程服务器同时下载多个文件吗?
SftpTest.java
public class SftpTest {
private static List<SftpAccessor> accessorList = new ArrayList<SftpAccessor>();
private static List<Payload> files = new ArrayList<Payload>();
private static ExecutorService writerThreadPool = Executors.newFixedThreadPool(10);
public static void main(String args[]) throws JSchException, InterruptedException {
SSH srcServer = new SSH();
srcServer.setHostname("10.22.65.140");
srcServer.setKey("D:\\jars\\dmwvmcol01.ec2user.pem");
srcServer.setPort("22");
srcServer.setUsername("ec2-user");
SftpAccessor acc = new SftpAccessor(srcServer);
accessorList.add(acc);
files.addAll(acc.ls("/data/test/src", false, "*", 1));
for (Payload file : files) {
writerThreadPool.submit(new LocalWriterThread(file));
}
writerThreadPool.shutdown();
writerThreadPool.awaitTermination(20, TimeUnit.MINUTES);
}}
LocalWriterThread.java
public class LocalWriterThread implements Callable<String> {
private Payload payload;
public LocalWriterThread(Payload payload) {
this.payload = payload;
}
public String call() throws Exception {
String dest = "D:\\output\\jobsystemnew";
System.out.println(payload.getFilename());
File file = new File(dest + "/" + payload.getFilename());
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
copy(payload.getInputStream(), fos);
payload.setInputStream(null);
return "";
}
private void copy(InputStream is, OutputStream os) throws IOException {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
System.out.println("Started Copying file : " + payload.getFilename());
bis = new BufferedInputStream(is);
bos = new BufferedOutputStream(os);
byte[] buffer = new byte[1024];
while (bis.read(buffer) != -1) {
bos.write(buffer);
}
bos.flush();
System.out.println("Finished Copying file : " + payload.getFilename());
}
finally {
System.out.println("Closing input stream for " + payload.getFilename());
bis.close();
bos.close();
/*
* try { if (is != null) { is.close(); } } catch (Exception e) { System.out.println(" " + e + " : " + e.getMessage() + " unable to close input stream : " + payload.getFilename());
* e.printStackTrace(); }
*/
/*
* try { if (os != null) { os.close(); } } catch (Exception e) { System.out.println(" " + e + " : " + e.getMessage() + " unable to close output stream : " + payload.getFilename());
* e.printStackTrace(); }
*/
}
}}
SSH.java
public class SSH {
String hostname;
String port;
String username;
String key;
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
} }
SftpAccessor.java
public class SftpAccessor {
private JSch jsch = new JSch();
private ChannelSftp channelSftp = null;
private Session session = null;
String errorMsg = null;
public SftpAccessor(SSH ssh) throws JSchException {
jsch.addIdentity(ssh.getKey());
session = jsch.getSession(ssh.getUsername(), ssh.getHostname(), Integer.parseInt(ssh.getPort()));
session.setHostKeyAlias(ssh.getKey());
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
channelSftp = (ChannelSftp) session.openChannel("sftp");
channelSftp.connect();
}
public List<Payload> ls(String directory, boolean recursive, String filemask, int delayMinutes) {
List<Payload> files = new ArrayList<Payload>();
try {
channelSftp.cd(directory);
@SuppressWarnings("unchecked")
Vector<ChannelSftp.LsEntry> entries = channelSftp.ls(filemask);
for (ChannelSftp.LsEntry entry : entries) {
try {
if (entry.getAttrs().isDir()) {
if (recursive) {
List<Payload> filesToAdd = ls(directory + "/" + entry.getFilename(), recursive, filemask, delayMinutes);
files.addAll(filesToAdd);
}
}
else {
Date lastmodified = new Date(entry.getAttrs().getMTime() * 1000L);
Date currdate = new Date(new Date().getTime() - (delayMinutes * 60 * 1000L));
if (lastmodified.before(currdate)) {
String filename = entry.getFilename();
entry.getAttrs().getMTime();
Payload file = new Payload();
System.out.println("Getting input Stream for " + directory + "/" + filename);
file.setInputStream(channelSftp.get(directory + "/" + filename));
file.setFilename(filename);
file.setLastModified(lastmodified);
files.add(file);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
catch (SftpException e) {
}
return files;
}}
有效载荷.java
public class Payload {
private String filename;
private InputStream inputStream;
private Date lastModified;
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public Date getLastModified() {
return lastModified;
}
public void setLastModified(Date lastModified) {
this.lastModified = lastModified;
}
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}}
最佳答案
JSch 不是线程安全的。即使是这样,通过单个 SSH session 使用并行下载也几乎没有任何性能优势。它会像串行下载一样慢。此外,您可能会达到并发文件句柄的服务器端限制。
您应该为每个线程/下载打开一个单独的 session 。
关于java - 使用JSch使用多线程下载文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29267614/
当我尝试通过我的 .exe 文件从 url 下载 .pdf 文件时出现以下错误。 The server committed a protocol violation. Section=Response
我是一家非营利组织的 G Suite 管理员,刚刚发现数据导出功能,这似乎是个人帐户的外卖。 导出文件已准备好,现在可以从 Google Cloud Platform Storage 中的存储桶下载。
导航 引言 总体思路 七牛云相关的配置文件 获取七牛云上传token 相关类定义 核心代码实现 获取七牛云图片下载链接 公开空
这不是后端编程问题。我只能修改标记或脚本(或文档本身)。我在这里问的原因是因为我对适当术语的所有搜索都不可避免地导致有关编程此功能的问题和解决方案。我不是试图通过编程来强制它;我必须找出此 PDF 行
您好,我已在 Google AdSense 中注册,我想使用适用于 iOS 的 SDK,但目前我找不到 SDK 下载链接。 我的申请已获批准。 任何人都知道如何下载这个sdk。 我使用这个链接来描述如
我需要为当前在 SourceForge 上的 github 项目提供二进制文件和文档。在那里,我可以为我需要的下载提供一个目录结构,因为我必须为大约 10 个不同的操作系统提供几个版本。 github
我从 Canvas 下载绘图时遇到问题。这是我的代码: function downloadCanvas(link, canvasId, filename) { link.href =
ASP.NET 项目 我将使用 Azure 进行存储。问题(要求): 在我的项目中,我让注册用户下载文件。但我不希望用户将此下载链接分享给未注册的人(例如:我给注册用户的下载链接只能在他们的计算机上下
我编写了一个servlet,用于检查http header ,但我不知道为什么当页面加载时,它会自动开始下载。 /* * To change this template, choose To
我正在尝试将下载添加到我的网络浏览器,但遇到的问题是获取您尝试下载的文件的名称。这是我的下载代码: engine.locationProperty().addListener(new ChangeLi
我正在尝试下载网站的 html: String encoding = "UTF-8"; HttpContext localContext = new BasicHttpContext();
我制作了一个带有“开始下载”按钮的框架,用于从网站下载 JAR。 问题是每当我点击开始下载按钮时,整个框架就会卡住,直到下载完成,然后就正常了。 我该如何解决这个问题? 这是单击按钮时执行的代码 p
我得到这段代码来实现一些东西,它可以帮助我从给定的 URL 下载文件。 -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSes
我正在尝试创建一个 Controller 来使用流方法下载和上传文件,在我的例子中,所有文件都作为 Blob 保存在数据库中。我阅读了 Jboss Netty 的文档,但我认为这不是我的最佳解决方案。
下载并保存文件 let destination: DownloadRequest.DownloadFileDestination = { _, _ in // var fileURL = sel
使用 htaccess 我基本上试图禁止访问该页面,即 http://example.com , 但它仍然允许人们下载文件,如果他们有直接链接即 http://example.com/hi.zip .
我正在寻求将脚本与我的控制面板集成,并且由于我是新手脚本编写者而遇到问题。我想做的是用 1 个脚本下载一个文件并解压它。 示例: wget http://example.com/example.tar
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
这个问题在这里已经有了答案: Top techniques to avoid 'data scraping' from a website database (14 个答案) 关闭 5 年前。 我有
这个问题在这里已经有了答案: Reading and parsing email from Gmail using C#, C++ or Python (6 个答案) 关闭 7 年前。 我只是想,是
我是一名优秀的程序员,十分优秀!