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

Android app通过jcifs-ng实现Samba连接共享文件夹

Android端使用Samba连接共享文件夹,下载或上传文件的功能实现。如果你是用jcifs工具包,那么你要注意jcifs-ng 和 jcifs 支持的SMB版本区别。

JCIFS-NG的github地址
JCIFS官网地址 这里有关于jciffsjcifs-codelibsjcifs-ngsmbj的详细介绍

对比

  • 支持的smb版本
    jcifs:
    仅支持SMB 1.0(CIFS), jcifs 最初是针对 SMB 1.0(CIFS)协议开发的,因此它是对 SMB 1.0 版本的最好支持。
    jcifs-ng 2.1:
    此版本默认启用SMB2支持,并包含一些实验性的SMB3.0支持。
    协商的协议级别现在可以使用jcifs.smb.client.minVersion和jcifs.smb.client.maxVersion进行控制(这会弃用jcifs.smb.client.enableSMB2/jcifs.sm b.client.disableSMB1属性)。默认的最小/最大版本是SMB1到SMB210。
    此版本禁止服务器浏览(即服务器/工作组枚举),并包含有关身份验证的一些突破性API更改。
    jcifs-ng 2.0:
    此版本支持SMB2(2.02协议级别),目前仅在配置了jcifs.smb.client.enableSMB2的情况下宣布支持SMB2,但如果服务器不支持SMB1方言,也可以选择支持SMB2。

  • 开发状态:
    jcifs: jcifs 是最初由 Mike Allen 开发的 Java CIFS 实现,最后一个官方发布版本是 1.3.19,发布于 2007 年。此后,jcifs 进入了维护模式,不再进行主要更新。
    jcifs-ng: jcifs-ng(jcifs-next generation)是基于 jcifs 的一个分支,由 Alexander Böhm 等人开发。它是对 jcifs 的改进和扩展,具有更现代化的代码结构和更多功能。jcifs-ng 目前仍在活跃地开发和维护。

  • 功能和性能:
    jcifs-ng 在功能和性能上进行了改进和优化,相比于原始的 jcifs,它提供了更多的功能和更好的性能。例如,jcifs-ng 支持更多的 SMB 协议特性,并且在速度和稳定性方面进行了改进。

  • API 和使用方式:
    jcifs-ng 在 API 和使用方式上与 jcifs 类似,但可能会有一些差异和改进。因此,如果你已经熟悉 jcifs,那么迁移到 jcifs-ng 应该相对容易。

这里使用的是jcifs-ng 2.1.9

添加依赖

implementation 'eu.agno3.jcifs:jcifs-ng:2.1.9'

代码实现(Kotlin)

package com.xxx.customerimport android.util.Log
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import jcifs.CIFSContext
import jcifs.context.SingletonContext
import jcifs.smb.SmbException
import jcifs.smb.SmbFile
import jcifs.smb.SmbFileInputStream
import jcifs.smb.SmbFileOutputStream
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.util.Propertiesclass SambaManager {private val SAMBA_SERVER_IP = "your server ip"private val SAMBA_USERNAME = "username"private val SAMBA_PASSWORD = "password"companion object {private const val TAG = "SambaManager"private var mCIFSContext: CIFSContext? = null}/*** 上传文件到共享文件夹指定目录* @param viewLifecycleOwner* @param localFilePathList 待上传的本地文件路径列表* @param remoteFolderPath 要上传到的远端路径,*        如果共享文件夹为shared_folder,则该路径应该包含shared_folder,*        如:shared_folder/ 或 shared_folder/xxx* @param onComplete 任务完成厚的回调*/fun uploadFiles(viewLifecycleOwner: LifecycleOwner,localFilePathList: MutableList<String>,remoteFolderPath: String,onComplete: (Int) -> Unit) {viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {var count = 0val smbContext = getCIFSContext()for (filePath in localFilePathList) {val localFile = File(filePath)if (!localFile.exists()) {continue}val folderUrl = "smb://${SAMBA_SERVER_IP}/${remoteFolderPath.trim('/')}"val smbFolder = try {SmbFile(folderUrl, smbContext)} catch (e: IOException) {Log.e(TAG, "Failed to create SmbFile", e)continue}//创建目录smbFolder.mkdirs()val url = "$folderUrl/${localFile.name}"val smbFile = try {SmbFile(url, smbContext)} catch (e: IOException) {Log.e(TAG, "Failed to create SmbFile", e)continue}try {if (smbFile.exists()) {smbFile.delete()}smbFile.createNewFile()} catch (e: SmbException) {Log.e(TAG, "Failed to create new SmbFile", e)continue}try {val outputStream = BufferedOutputStream(SmbFileOutputStream(smbFile))val inputStream = BufferedInputStream(FileInputStream(localFile))inputStream.use { input ->outputStream.use { output ->val buffer = ByteArray(1024)var bytesRead: Intwhile (input.read(buffer).also { bytesRead = it } != -1) {output.write(buffer, 0, bytesRead)}}}count++} catch (e: IOException) {Log.e(TAG, "Failed to download file", e)continue}}onComplete(count)}}/*** 批量下载文件* @param viewLifecycleOwner* @param remoteFilePathList 需要下载的远端文件路径列表* @param localFolderPath 本地文件夹路径,用于保存下载的文件* @param onComplete 任务完成后的回调*/fun downloadFiles(viewLifecycleOwner: LifecycleOwner,remoteFilePathList: MutableList<String>,localFolderPath: String,onComplete: (Int) -> Unit) {viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {var count = 0val smbContext = getCIFSContext()for (path in remoteFilePathList) {val strList = path.split("/")var fileName = strList[strList.lastIndex]val url = "smb://${SAMBA_SERVER_IP}/${path.trimStart('/')}"val smbFile = try {SmbFile(url, smbContext)} catch (e: IOException) {Log.e(TAG, "Failed to create SmbFile", e)continue}if (!smbFile.exists()) {Log.e(TAG, "File does not exist: ${path}")continue}try {val localFile = File("$localFolderPath/$fileName")if (!localFile.exists()) {localFile.createNewFile()}val inputStream = BufferedInputStream(SmbFileInputStream(smbFile))val outputStream = BufferedOutputStream(FileOutputStream(localFile))inputStream.use { input ->outputStream.use { output ->val buffer = ByteArray(1024)var bytesRead: Intwhile (input.read(buffer).also { bytesRead = it } != -1) {output.write(buffer, 0, bytesRead)}}}count++} catch (e: IOException) {Log.e(TAG, "Failed to download file", e)continue}}onComplete(count)}}/*** 获取包含配置参数的CIFSContext*/private fun getCIFSContext(): CIFSContext {if (mCIFSContext == null) {val properties = Properties()properties.setProperty("jcifs.smb.client.domain", SAMBA_SERVER_IP);properties.setProperty("jcifs.smb.client.username", SAMBA_USERNAME);properties.setProperty("jcifs.smb.client.password", SAMBA_PASSWORD);SingletonContext.init(properties) //init只能初始化一次mCIFSContext = SingletonContext.getInstance()}return mCIFSContext!!}
}

相关文章:

Android app通过jcifs-ng实现Samba连接共享文件夹

Android端使用Samba连接共享文件夹&#xff0c;下载或上传文件的功能实现。如果你是用jcifs工具包&#xff0c;那么你要注意jcifs-ng 和 jcifs 支持的SMB版本区别。 JCIFS-NG的github地址 JCIFS官网地址 这里有关于jciffs、jcifs-codelibs、jcifs-ng、smbj的详细介绍 对比 支…...

linux开发笔记(buildroot打包镜像)

参考文章:https://www.cnblogs.com/arnoldlu/p/9553995.html mangopi_r3的buildroot在编译完成后会将所有镜像打包到一起。与之有关的buildroot配置项为 BR2_ROOTFS_POST_IMAGE_SCRIPT"board/allwinner/generic/scripts/genimage.sh" genimage.sh内容如下 #!/bin…...

预编码算法学习笔记

预编码算法是无线通信系统中的一项关键技术&#xff0c;它能够在发送端对信号进行处理&#xff0c;以提高系统的可靠性和频谱效率。以下是关于预编码算法的详细学习笔记。 1. 引言 在无线通信系统中&#xff0c;由于存在多径效应、信号衰减以及干扰等因素&#xff0c;接收到的…...

2024OD机试卷-最长子字符串的长度(一) (java\python\c++)

题目:最长子字符串的长度(一) 题目描述 给你一个字符串 s,首尾相连成一个环形,请你在环中找出 ‘o’ 字符出现了偶数次最长 子字符串 的长度。 输入描述 输入是一个小写字母组成的字符串 输出描述 输出是一个整数 用例1 输入 alolobo 输出 6 用例2 输入 looxdolx …...

docker 部署并运行一个微服务

要将微服务部署并运行在Docker容器中&#xff0c;你需要按照以下步骤操作&#xff1a; 编写Dockerfile&#xff1a;在项目根目录下创建一个名为Dockerfile的文件&#xff0c;并添加以下内容&#xff1a; # 使用一个基础的Docker镜像 FROM docker-image# 将项目文件复制到容器…...

Hive on Tez 作业优化参数

常用参数 参数名 参数说明 默认值 所在配置文件 关联问题 hive.tez.container.size Tez AppMaster向RM申请的container大小 -(单位:MB) hive-site.xml OOM tez.runtime.io.sort.mb 这个参数设定了 Tez 运行排序操作时可用的最大内存。排序操作的内存大小也会影响到排序的效率…...

flink mysql数据表同步API CDC

概述&#xff1a; CDC简介 Change Data Capture API CDC同步数据代码 package com.yclxiao.flinkcdcdemo.api;import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.ververica.cdc.connectors.mysql.source.MySqlSource; import com.verv…...

AI大模型探索之路-训练篇21:Llama2微调实战-LoRA技术微调步骤详解

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…...

如何使用client-go构建pod web shell

代码示例及原理 原理是利用websocket协议实现对pod的exec登录&#xff0c;利用client-go构造与远程apiserver的长连接&#xff0c;将对pod容器的输入和pod容器的输出重定向到我们的io方法中&#xff0c;从而实现浏览器端的虚拟终端的效果消息体结构如下 type Connection stru…...

AI工具摸索-关于写作(1)

虽然人工智能工具非常多,但是如果想要成为生产力,能达标的工具仍然非常少,除了最常用的chatgpt,其他的工具真的能达标吗,这篇文章主要就是对比市面上的一些工具&#xff0c; 但我这个人非常执拗,我认为作为生产力工具的功能必然是可以真正帮助我们的,而不是说作为一个写作工具结…...

昂科烧录器支持O2Micro凹凸科技的电池组管理IC OZ7708

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表&#xff0c;其中O2Micro凹凸科技的电池组管理IC OZ7708已经被昂科的通用烧录平台AP8000所支持。 OZ7708是一款高度集成、低成本的电池组管理IC&#xff0c;适用于5~8s Li-Ion/Polymer电池组&a…...

Spring Cloud Gateway详解

文章目录 Gateway搭建路由&#xff08;route&#xff09;断言&#xff08;Predicate &#xff09;自定义断言 过滤器&#xff08;filter&#xff09;自定义全局过滤器 引言 在传统的单体项目中&#xff0c;前端和后端的交互相对简单&#xff0c;只需通过一个调用地址即可实现。…...

信息系统项目管理师0103:初步可行性研究(7项目立项管理—7.2项目可行性研究—7.2.2初步可行性研究)

点击查看专栏目录 文章目录 7.2.2初步可行性研究1.初步可行性研究定义2.辅助研究的目的和作用3.初步可行性研究的作用4.初步可行性研究的主要内容记忆要点总结7.2.2初步可行性研究 1.初步可行性研究定义 初步可行性研究一般是在对市场或者客户情况进行调查后,对项目进行的初步…...

Linux 系统中,nl命令用于计算文件中的行号

在 Linux 系统中&#xff0c;nl命令用于计算文件中的行号。它可以将输出的文件内容自动加上行号&#xff0c;并且可以通过不同的选项来设置行号的显示方式&#xff0c;包括行号的位数、是否自动补齐 0 等。其命令格式为&#xff1a;nl(选项)…(文件)…。以下是一些常见的选项&a…...

知从科技战略客户经理张志强受邀出席2024 AutoSec中国汽车网络安全与数据安全峰会

4月11-12日&#xff0c;AutoSec8周年年会暨中国汽车网络安全及数据安全合规峰会在上海成功举办。此次峰会吸引了来自全球各地的头部汽车网络安全企业、OEM厂商、安全专家和学者等齐聚盛会&#xff0c;零距离共话智能网联汽车产业的新发展、新趋势。 知从科技董事长成云霞亲自带…...

2024.5.12 Pandas 基础语法day02

#describe()作用是计算出各个列的描述行统计量如平均数&#xff0c;方差&#xff0c;最大值&#xff0c;最小值&#xff0c;四分位数&#xff0c;返回类型是 #pandas.core.frame.DataFrame import pandas as pd df pd.read_csv("Nowcoder.csv") print(df.describe()…...

Stable Diffusion是什么?

目录 一、Stable Diffusion是什么&#xff1f; 二、Stable Diffusion的基本原理 三、Stable Diffusion有哪些运用领域&#xff1f; 一、Stable Diffusion是什么&#xff1f; Stable Diffusion是一个先进的人工智能图像生成模型&#xff0c;它能够根据文本描述创造出高质量的图…...

Netty源码分析二NioEventLoop 剖析

剖析方向 NioEventLoop是一个重量级的类&#xff0c;其中涉及到的方法都有很复杂的继承关系&#xff0c;调用链&#xff0c;要想把源码全部过一遍工作量实在是太大了&#xff0c;于是小编就基于下面的这些常见的问题来对NioEventLoop的源码来进行剖析 1.Seletor何时创建 1.1Se…...

chatGLM或chatgpt:什么是tokens以及如何计算tokens长度?

token是什么? 简单的来说tokens就是大语言模型输入的向量数据,它是从原始的文本转化而来。 比如 输入:here is a text demo tokens为:[64790, 64792, 985, 323, 260, 2254, 16948] 解码:将tokens转化为文本 [‘[gMASK]’, ‘sop’, ‘▁here’, ‘▁is’, ‘▁a’, ‘▁…...

springcloudalibaba版本发布说明

版本发布说明 | https://sca.aliyun.com 2.2.x 分支 适配 Spring Boot 为 2.4&#xff0c;Spring Cloud Hoxton 版本及以下的 Spring Cloud Alibaba 版本按从新到旧排列如下表&#xff08;最新版本用*标记&#xff09;&#xff1a; Spring Cloud Alibaba VersionSpring Cloud…...

曾经我和大模型交流业务实现记录

第一次&#xff1a; 我有一组子组件11个&#xff0c;通过子组件的不同组合&#xff0c;可以组成表单&#xff0c;这些表单让不同的用户使用&#xff0c;表单组成公共的内容&#xff0c;让大部分用户使用&#xff0c;当然用户可以在这些表单的基础上修改一些默认值&#xff0c;变…...

【Java低代码组件调试黄金法则】:20年架构师亲授5大高频故障定位技巧,90%开发者从未听说

第一章&#xff1a;Java低代码组件调试的本质与认知跃迁Java低代码平台并非屏蔽复杂性&#xff0c;而是将复杂性重新封装、可视化与可追溯化。调试低代码组件的本质&#xff0c;是穿透表层拖拽逻辑&#xff0c;定位其背后生成的Java字节码、Spring Bean生命周期行为、以及运行时…...

DSP题目:FFT算法的Matlab实现及其应用研究

DSP 题目&#xff1a;FFT算法的Matlab实现及应用研究最近帮室友调毕设的信号处理部分&#xff0c;他拿了个麦克风录的杂音&#xff0c;想把背景的50Hz工频噪音去掉&#xff0c;上来就问我“为啥我fft出来的峰不对”——害&#xff0c;这问题我刚学DSP的时候也踩过无数坑&#x…...

LCC-S无线电能传输的Pi移相控制与SS结构效果显著

LCC-S无线电能传输pi移相控制输出电压&#xff0c;效果很棒 SS结构&#xff0c;与其他低阶高阶拓扑也可以做 SS拓扑最近在捣鼓无线电能传输系统时&#xff0c;意外发现LCC-S拓扑搭配π型移相控制&#xff0c;输出效果堪比美颜相机里的磨皮功能。这货不仅能把输出电压纹波压得比…...

2026年4月如何集成OpenClaw?华为云保姆级10分钟安装及百炼APIKey配置方法

2026年4月如何集成OpenClaw&#xff1f;华为云保姆级10分钟安装及百炼APIKey配置方法。OpenClaw&#xff08;原Clawdbot&#xff09;作为2026年主流的AI自动化助理平台&#xff0c;可通过阿里云轻量服务器实现724小时稳定运行&#xff0c;并快速接入钉钉&#xff0c;让AI在企业…...

Windows驱动存储深度管理:从问题诊断到系统优化的完整解决方案

Windows驱动存储深度管理&#xff1a;从问题诊断到系统优化的完整解决方案 【免费下载链接】DriverStoreExplorer Driver Store Explorer [RAPR] 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 问题发现&#xff1a;驱动管理中的隐形痛点与风险 系…...

论文阅读 AIED 2024 Coding with AI: How Are Tools Like ChatGPT Being Used by Students in Foundational Pro

总目录 大模型相关研究&#xff1a;https://blog.csdn.net/WhiffeYF/article/details/142132328 Coding with AI: How Are Tools Like ChatGPT Being Used by Students in Foundational Programming Courses https://link.springer.com/chapter/10.1007/978-3-031-64299-9_20…...

防爆气象站为什么能够成为化工行业的必备仪器

防爆气象站能够成为化工行业的必备仪器&#xff0c;主要基于其本质安全设计、多参数精准监测、实时预警能力、环境适应性、合规管理支持及生产优化价值六大核心优势&#xff0c;这些特性直接解决了化工行业在安全管控、工艺控制及合规运营中的关键痛点。一、本质安全设计&#…...

从 14 万美元支付事故看:AI 写的代码过了所有测试,为什么活不过生产?

我审计过的一家科技公司&#xff0c;曾因一段 AI 生成的异步支付处理代码&#xff0c;遭遇了一场灾难性的生产事故。这段代码完美通过了所有自动化检查、单元测试与集成测试&#xff0c;标注着「All checks passed」被顺利合并到生产环境&#xff0c;最终却触发了竞态条件与重复…...

汽车动力性能计算工具插件:一键测算电机需求与整车性能,工程师专属轻量级辅助软件

温馨提示&#xff1a;文末有联系方式插件核心功能亮点 本款汽车动力性系统专用计算小工具&#xff0c;可精准推演电机功率与扭矩需求&#xff0c;同步输出整车加速性能、最大爬坡度、最高稳定车速等关键动力参数&#xff0c;覆盖常规工况与典型驱动场景&#xff0c;满足前期方案…...