当前位置: 首页 > news >正文

android--studio用sshj,而不是sftp上传和下载文件以及错误提醒

主要代码:SFTPUtil.java, 使用sshj,而不是sftp

package com.mth.sftp_filehanlder;import net.schmizz.sshj.DefaultConfig;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.sftp.RemoteResourceInfo;
import net.schmizz.sshj.sftp.SFTPClient;
import net.schmizz.sshj.sftp.SFTPException;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;import java.io.File;
import java.io.IOException;
import java.util.List;/*** SFTP工具类(基于SSHJ实现,方法签名与SFTPUtil_backup一致)*/
public class SFTPUtil {private static final String TAG = "MTH_Morgan"; public static final String host = "your ip address";public static final int port = 22;public static final String username = "your login-in name";public static final String password = "your login-in password";public static final String remoteDir = "your path to the file you will handle";/*** 连接SFTP服务器*/public static SSHClient connect(String host, Integer port, String user, String password) throws IOException {SSHClient ssh = new SSHClient(new DefaultConfig());ssh.addHostKeyVerifier(new PromiscuousVerifier());ssh.connect(host, port);ssh.authPassword(user, password);return ssh;}/*** 下载文件或目录(递归)*/public static void download(String directory, String srcFile, String saveFile, SFTPClient sftp) throws IOException {String remotePath = srcFile;File localTarget = new File(saveFile);try {List<RemoteResourceInfo> entries = sftp.ls(remotePath);// 如果是单文件if (entries != null && entries.size() == 1) {RemoteResourceInfo single = entries.get(0);if (!single.isDirectory() && normalizePath(single.getPath()).equals(normalizePath(remotePath))) {if (localTarget.exists() && localTarget.isFile()) {sftp.get(remotePath, localTarget.getPath());} else {if (!localTarget.exists()) localTarget.mkdirs();String filename = new File(remotePath).getName();String localFilePath = localTarget.getPath() + File.separator + filename;sftp.get(remotePath, localFilePath);}return;}}// 否则递归下载目录if (entries == null || entries.isEmpty()) return;for (RemoteResourceInfo entry : entries) {String name = entry.getName();if (".".equals(name) || "..".equals(name)) continue;if (entry.isDirectory()) {String childRemotePath = remotePath.endsWith("/") ? remotePath + name : remotePath + "/" + name;String childLocalPath = localTarget.getPath() + File.separator + name;File dirLocal = new File(childLocalPath);if (!dirLocal.exists()) dirLocal.mkdirs();download(directory, childRemotePath, childLocalPath, sftp);} else {if (!localTarget.exists()) localTarget.mkdirs();String remoteFilePath = remotePath.endsWith("/") ? remotePath + name : remotePath + "/" + name;String localFilePath = localTarget.getPath() + File.separator + name;sftp.get(remoteFilePath, localFilePath);}}} catch (SFTPException lsEx) {// 如果 ls 失败,尝试直接下载文件try {if (localTarget.exists() && localTarget.isFile()) {sftp.get(remotePath, localTarget.getPath());} else {if (!localTarget.exists()) localTarget.mkdirs();String filename = new File(remotePath).getName();String localFilePath = localTarget.getPath() + File.separator + filename;sftp.get(remotePath, localFilePath);}} catch (SFTPException getEx) {throw new IOException("Remote path cannot be listed or downloaded. ls error: " + lsEx.getMessage()+ " ; get error: " + getEx.getMessage(), getEx);}}}private static String normalizePath(String p) {if (p == null) return "";return p.replaceAll("/+", "/").replaceAll("/$", "");}/*** downloadtxt:下载指定文件到本地路径*/public static void downloadtxt(String localPath, String uploadFile) {System.out.println(TAG + " downloadtxt => " + remoteDir);downloadfile(remoteDir, remoteDir + "/" + uploadFile, localPath);}/*** downloadfile:下载文件或目录*/public static void downloadfile(String remoteDir, String remoteDirtxt, String localFile) {SSHClient ssh = null;SFTPClient sftp = null;try {System.out.println(TAG + " => downloadfile");ssh = connect(host, port, username, password);sftp = ssh.newSFTPClient();System.out.println(TAG + " remoteDir=" + remoteDir);System.out.println(TAG + " remoteDirtxt=" + remoteDirtxt);System.out.println(TAG + " localFile=" + localFile);download(remoteDir, remoteDirtxt, localFile, sftp);} catch (Exception e) {System.out.println(TAG + " downloadfile error: " + e);e.printStackTrace();} finally {try {if (sftp != null) sftp.close();if (ssh != null) ssh.disconnect();} catch (IOException e) {e.printStackTrace();}}}/*** putFile:上传文件*/public static void putFile(String localPath, String localFile, String remotePath, SFTPClient sftp) throws IOException {try {sftp.mkdirs(remotePath);} catch (Exception ignored) {}String localFilePath = localPath.endsWith(File.separator) ? localPath + localFile : localPath + File.separator + localFile;String remoteFilePath = remotePath.endsWith("/") ? remotePath + localFile : remotePath + "/" + localFile;System.out.println(TAG + " => Uploading " + localFilePath + " to " + remoteFilePath);sftp.put(localFilePath, remoteFilePath);}/*** uploadtxt:上传文件*/public static void uploadtxt(String localPath, String uploadFile) {SSHClient ssh = null;SFTPClient sftp = null;try {ssh = connect(host, port, username, password);sftp = ssh.newSFTPClient();putFile(localPath, uploadFile, remoteDir, sftp);} catch (Exception e) {e.printStackTrace();} finally {try {if (sftp != null) sftp.close();if (ssh != null) ssh.disconnect();} catch (IOException e) {e.printStackTrace();}}}
}

build文件:

    implementation 'com.hierynomus:sshj:0.33.0'//implementation 'org.bouncycastle:bcprov-jdk15on:1.70'// 添加 Conscrypt(提供 Android 上完整的 ECDSA/ECDH 支持)implementation 'org.conscrypt:conscrypt-android:2.5.2'// 可选:让 sshj 的日志能输出到 logcat(便于调试)implementation 'org.slf4j:slf4j-android:1.7.36'

服务器上不需要特别设定hotkey

sudo nano /etc/ssh/sshd_config

在这里插入图片描述

  1. 错误代码
downloadfile error: net.schmizz.sshj.transport.TransportException: Connection reset

解决方法: 公司内部网络,IP限制,需要用外网

  1. 错误代码
downloadfile error: net.schmizz.sshj.transport.TransportException: The BC provider no longer provides an implementation for MessageDigest.SHA-256.  Please see https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html for more details.

解决办法:
》》 增加My Application.java
在这里插入图片描述

package com.mth.sftp_filehanlder;import android.app.Application;
import android.util.Log;import androidx.multidex.MultiDex;import org.conscrypt.Conscrypt;import java.security.Provider;
import java.security.Security;public class MyApplication extends Application {private static final String TAG = "MTH_Conscrypt";@Overridepublic void onCreate() {super.onCreate();// MultiDex 支持(minSdk < 21 时需要)try {MultiDex.install(this);} catch (Throwable t) {Log.w(TAG, "MultiDex.install failed", t);}// 1) 插入 Conscrypt 到 provider 列表首位try {Security.insertProviderAt(Conscrypt.newProvider(), 1);Log.i(TAG, "Conscrypt provider inserted");} catch (Throwable t) {Log.e(TAG, "Failed to insert Conscrypt provider", t);}// 2) 尝试移除系统/应用范围内的 BC provider(避免 sshj 指向不完整的 BC 实现)try {// 如果存在,会被移除;若不存在或不允许移除,会抛异常,我们捕获并记录但不终止应用启动if (Security.getProvider("BC") != null) {Security.removeProvider("BC");Log.i(TAG, "Removed provider: BC");} else {Log.i(TAG, "Provider BC not present (no removal needed)");}} catch (Throwable t) {Log.w(TAG, "Failed to remove provider BC (continuing)", t);}// 3) 打印当前 provider 列表,便于在 logcat 中确认优先级与是否已移除 BCtry {Provider[] providers = Security.getProviders();for (Provider p : providers) {Log.i(TAG, "Provider: " + p.getName() + " ver:" + p.getVersion());}} catch (Throwable t) {Log.w(TAG, "print providers failed", t);}}
}

并且在AndroidManifest.xml注明:
在这里插入图片描述

3 build错误

Unsupported class file major version 59

解决办法:
gradle.properties文件如下就可:

# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=false
http://www.dtcms.com/a/610720.html

相关文章:

  • Rust的内存安全与实战落地的直观解析
  • 网站建设系统规划怎样在赶集微网站做微招聘信息
  • 写作网站保底和全勤的区别用二级域名做网站对seo
  • 升鲜宝分拣系统 具体实现(一)
  • 具身智能-一文详解视觉-语言-动作(VLA)大模型(3)
  • 多模态学习核心技术与典型场景对照表
  • 3d网站设计7免费crm
  • 常德烟机网站上市公司集团网站建设
  • MySQL -- 库的操作
  • 网站开发文档docwordpress文章和页面
  • 番禺核酸检测点在哪石家庄网站建设seo公司
  • 人力资源网站开发说明书网站没被百度收录
  • 【深度学习新浪潮】算法工程师如何入门芯片硬软件设计工作?
  • JM20329是一款高性能、低功耗的USB桥接芯片,实现串行接口(如SATA、IDE)与USB接口之间的数据转换。
  • 微调模型过程中,发现欠拟合的措施
  • 网站代发怎么做网站建设标语文案
  • Wisdom Lens:开启物联网固件模糊测试新时代
  • 番禺区建设局网站影视公司起名
  • js(BOM)基础:15、Navigator对象、History对象、Location对象、定时(器)调用、demo(定时器实现图形变化动画)
  • 屏幕捕捉工具 (Screen Capture Tool)
  • 分离Hadoop客户端单独使用
  • 12306网站 谁做的网络营销八大工具
  • 渭南商铺网站建设关于文明网站建设存在的问题
  • C语言编译程序及其优化策略|详细解析如何提高C语言编译效率与代码执行性能
  • 通过 MQTT 命令控制 RV1106 的 WebRTC 推流启停” 及 “30 分钟无命令自动停止”
  • C++中将FlatBuffers序列化为JSON
  • 营销网站制作平台有哪些企业网站特色建设
  • pyinstaller 打包报错hook-matplotlib.backends.py
  • 盐城网站建设建站羽毛球最新赛事
  • 如何用dw做网站wordpress自动上传图片