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

C#实现访问远程硬盘(附源码)

在现实场景中,我们经常用到远程桌面功能,而在某些场景下,我们需要使用类似的远程硬盘功能,这样能非常方便地操作对方电脑磁盘的目录、以及传送文件。那么,这样的远程硬盘功能要怎么实现了?

这次我们将给出一个完整的Demo来演示远程硬盘要怎么实现,同时,这个Demo也给出了个人网盘是如何实现的。个人网盘可以看做是远程硬盘应用的一个特例,即,个人网盘就是访问服务器上的一个特定文件夹。废话不多说,先上图看看这个远程硬盘Demo的基本功能。

一. 远程硬盘功能展示

打开到对方的远程磁盘后,我们就可以看到对方电脑的硬盘了,点击任何一个,就可以访问该盘下面的文件。

访问远程硬盘

双击文件,就可以下载文件到本地;右键菜单则可以上传本地文件到远程磁盘。

传送文件

二. 远程硬盘代码实现

在实现远程磁盘时,我们分为两个层面介绍,一个是底层业务通信层面,另一个是上层的UI展现层面。

1. 底层业务通信实现

比如,当我们使用远程磁盘功能时,最常见的就是去获取对方电脑某个目录下的所有文件及文件夹,那么,这个功能是怎么实现的了?

基于ESFramework,实现这点其实很简单,我们举例说明。以A用户作为磁盘的分享者,B用户作为远程磁盘的访问者,A和B都启动了该Demo的客户端并登录。此时,B要访问A用户电脑上某个目录下的文件列表,那么,B就可以给A发一个请求消息,并得到回复,如下所示(NDiskOutter 类的 GetSharedDirectory 方法):     

/// <summary>
/// 获取目标用户电脑上指定目录下的文件列表信息。
/// </summary>
/// <param name="ownerID">目标用户的账号(磁盘分享者)</param>
/// <param name="clientType">目标用户的设备类型</param>
/// <param name="netDiskID">网盘的标志。(对于远程磁盘而言,即OwnerID为某个用户的ID时,该参数可传null)。如果是群组共享的文件夹,则可以将其设置为对应的群组的ID。</param>
/// <param name="dirPath">指定目录的路径</param>
/// <returns>目录下的文件列表信息</returns>
public SharedDirectory GetSharedDirectory(string ownerID,ClientType clientType,string netDiskID ,string dirPath)
{ReqDirectoryContract contract = new ReqDirectoryContract(netDiskID, dirPath);byte[] res;if (!ownerID.Equals(NetServer.SystemUserID)) //远程磁盘{res = this.p2pQueryOutter.Query(ownerID, clientType, this.fileDirectoryInfoTypes.ReqDirectory, CompactPropertySerializer.Default.Serialize<ReqDirectoryContract>(contract), "");}else //网盘{res = this.customizeOutter.Query(this.fileDirectoryInfoTypes.ReqDirectory, CompactPropertySerializer.Default.Serialize<ReqDirectoryContract>(contract));}ResDirectoryContract resContract = CompactPropertySerializer.Default.Deserialize<ResDirectoryContract>(res, 0);return resContract.SharedDirectory;
}

无论是网盘,还是远程磁盘,都可以通过上述的代码来进行调用,以获取对方电脑指定目录下的文件列表。

(1)特别注意,上述代码中红色字体突出显示的Query方法,该方法的含义是:向对方(或服务器)发送 ReqDirectory 请求,并返回对方的应答结果。

(2)返回的 SharedDirectory 对象,里面包含了目录下的文件列表和子文件夹列表,可以通过 FileList 和 SubDirectorys 属性获取。

那么,A作为分享方,是如何处理来自B的 ReqDirectory 请求的了?

我们来看看 NDiskPassiveHandler 类的 HandleQuery 方法中对 ReqDirectory 请求的处理:

if (informationType == this.fileDirectoryInfoTypes.ReqDirectory){ReqDirectoryContract contract = CompactPropertySerializer.Default.Deserialize<ReqDirectoryContract>(info, 0);string fullPath = this.ConstructFullPath(contract.DirectoryPath);SharedDirectory dir = SharedDirectory.GetSharedDirectory(fullPath);return CompactPropertySerializer.Default.Serialize<ResDirectoryContract>(new ResDirectoryContract(dir));}

(1)首先,将二进制请求消息反序列化为 ReqDirectoryContract 对象,从中拿到对方想要请求的目录路径。

(2)通过 SharedDirectory 的静态方法 GetSharedDirectory 获取目标目录下的文件列表和子文件夹列表,并包装成 SharedDirectory 对象。

(3)将 SharedDirectory 对象序列化成二进制后,返回给请求方。

      上面就以请求指定目录下的文件列表及文件夹列表为例,说明了底层业务通信的过程。其它的业务通信就不再赘述了,大家可自行查看源码。

2. UI 实现 

      在客户端,最主要的UI控件就是 NDiskBrowser 的实现,它的功能主要有:

(1)浏览远程磁盘下的目录及文件。

(2)可从远程磁盘下载文件到本地电脑。

(3)可将本地文件上传到远程磁盘。

      我们仍然以浏览远程磁盘指定目录下的所有文件及文件夹为例,来看看 NDiskBrowser 是如何在UI展现的。

SharedDirectory sharedDirectory = this.nDiskOutter.GetSharedDirectory(this.ownerID, this.clientType, this.netDiskID , path);foreach (DirectoryDetail dirDetail in sharedDirectory.SubDirectorys)
{ListViewItem item = new ListViewItem(new string[] { dirDetail.Name, dirDetail.CreateTime.ToString(), "" }, 0);item.Tag = new FileOrDirectoryTag(dirDetail.Name, 0, dirDetail.CreateTime, false);this.listView_fileDirectory.Items.Add(item);
}foreach (FileDetail file in sharedDirectory.FileList)
{ListViewItem item = new ListViewItem(new string[] { file.Name, file.CreateTime.ToString(), PublicHelper.GetSizeString((uint)file.Size) }, this.GetIconIndex(file.Name));item.Tag = new FileOrDirectoryTag(file.Name, file.Size, file.CreateTime, true);item.ToolTipText = string.Format("大    小:{0}\n创建日期:{1}", PublicHelper.GetSizeString((uint)file.Size), file.CreateTime);this.listView_fileDirectory.Items.Add(item);
}

   在通过 NDiskOutter 的 GetSharedDirectory 方法拿到 SharedDirectory 对象后,就将其 SubDirectorys 所包含的每个子文件夹作为 ListViewItem  添加到 ListView 中显示出来;同时,也将其 FileList 所包含的每个文件作为 ListViewItem  添加到 ListView 中显示出来。这样就出现了我们之前截图的效果。

      NDiskBrowser 的实现代码虽然比较多,但是都很简单,大家下载源码后可自行查看。

三. 下载Demo源码及运行

1. Demo 源码下载:Oraycn.RemoteDisk.rar

2. 运行Demo

(1)运行服务端。

双击服务端运行目录下的 Oraycn.RemoteDisk.Server.exe ,即可启动服务端,如下截图所示:

远程硬盘服务端

(2)运行客户端。

修改客户端配置文件 Oraycn.RemoteDisk.exe.config 中的 ServerIP 为运行服务端电脑的 IP地址,然后双击 Oraycn.RemoteDisk.exe 启动客户端: 

远程硬盘客户端登录

账号密码随便填,登录成功后,进入主界面:

远程硬盘客户端主界面

此时,在主界面的输入框中填上对方的账号,点击“访问他的磁盘”按钮,如果对方在线,就会弹出此文第一张截图的窗体了。

如此,我们就可以完全的操控远程硬盘了。

关于远程硬盘,如果您有什么好点子,欢迎留言和我讨论,谢谢。

相关文章:

C#实现访问远程硬盘(附源码)

在现实场景中&#xff0c;我们经常用到远程桌面功能&#xff0c;而在某些场景下&#xff0c;我们需要使用类似的远程硬盘功能&#xff0c;这样能非常方便地操作对方电脑磁盘的目录、以及传送文件。那么&#xff0c;这样的远程硬盘功能要怎么实现了&#xff1f; 这次我们将给出…...

嵌入式软件学习记录 - DAY2

一、volatile 修饰符 1. 能修饰什么&#xff1f; 变量&#xff08;包括普通变量、指针、结构体成员等&#xff09;。不能修饰函数&#xff08;但函数参数或返回值可以是 volatile 类型&#xff09;。 2. 作用 告诉编译器不要优化该变量的访问&#xff1a;每次读取或写入该变…...

图片、音频、视频都能转?简鹿格式工厂了解一下

我们每天都会接触到各种各样的音视频和图片文件。无论是拍摄的照片、录制的视频&#xff0c;还是下载的音频资源&#xff0c;它们往往以不同的格式存在——有些适合分享&#xff0c;有些适合编辑&#xff0c;而有些则仅限特定设备或平台使用。格式不统一的问题&#xff0c;正在…...

Qt—用SQLite实现简单的注册登录界面

1.实现目标 本次实现通过SQLite制作一个简易的登录窗口&#xff0c;当点击注册按钮时&#xff0c;登录窗口会消失&#xff0c;会出现一个新的注册界面&#xff1b;完成注册或退出注册时&#xff0c;注册窗口会消失&#xff0c;重新出现登录窗口。注册过的用户信息会出现在SQLi…...

Nginx模块配置与请求处理详解

Nginx 作为模块化设计的 Web 服务器,其核心功能通过不同模块协同完成。以下是各模块的详细配置案例及数据流转解析: 一、核心模块配置案例 1. Handler 模块(内容生成) 功能:直接生成响应内容(如静态文件、重定向等) # 示例1:静态文件处理(ngx_http_static_module)…...

MySQL查询不区分大小写问题剖析

概述 在MySQL中&#xff0c;查询不区分大小写的问题通常与字符集的校对规则&#xff08;Collation&#xff09;有关。以下是详细解释和解决方案资料已经分类整理好&#xff1a;https://pan.quark.cn/s/f52968c518d3 一、原因分析 1. 默认校对规则 MySQL的默认校对规则&#…...

MySQL命令行导出数据(docker版本)

MySQL命令行导出数据(docker版本) 1、登录数据库 $mysql -h 10.1.1.143 -u root -p 2、用命令行从MySQL导出数据(无标题) #查看导出时可以存储的路径 mysql> SHOW VARIABLES LIKE secure_file_priv; ----------------------------------------- | Variable_name | Valu…...

分布式锁: Redisson红锁(RedLock)原理与实现细节

分布式锁是分布式系统的核心基础设施&#xff0c;但 单节点 Redis 锁在高可用场景下存在致命缺陷&#xff1a;当 Redis 主节点宕机时&#xff0c;从节点可能因异步复制未完成而丢失锁信息&#xff0c;导致多个客户端同时持有锁。为此&#xff0c;Redis 作者 Antirez 提出了 Red…...

Python 3.13.3 安装教程

原文来自&#xff1a;Python 3.13.3 安装教程 | w3cschool笔记 &#xff08;请勿标记为付费&#xff01;&#xff01;&#xff01;&#xff09; Python 是一种广泛使用的编程语言&#xff0c;广泛应用于 Web 开发、科学计算、数据处理、人工智能等领域。Python 3.13.3 作为 P…...

现代化水库运行管理矩阵平台如何建设?

政策背景 2023年8月24日&#xff0c;水利部发布的水利部关于加快构建现代化水库运行管理矩阵的指导意见中指出&#xff0c;在全面推进水库工程标准化管理的基础上&#xff0c;强化数字赋能&#xff0c;加快构建以推进全覆盖、全要素、全天候、全周期“四全”管理&#xff0c;完…...

2025程序设计天梯赛补题报告

2025程序设计天梯赛补题报告 仅包含L1 L2 L1-6 这不是字符串题 题目描述 因为每年天梯赛字符串题的解答率都不尽如人意&#xff0c;因此出题组从几年前开始决定&#xff1a;每年的天梯赛的 15 分一定会有一道字符串题&#xff0c;另外一道则一定不是字符串题。 小特现在有…...

SpringBoot3.4.5下Lombok的@Data注解不生效,解决方案

程序员Feri一名12年的程序员,做过开发带过团队创过业,擅长Java、嵌入式、鸿蒙、人工智能等,专注于程序员成长那点儿事,希望在成长的路上有你相伴&#xff01;君志所向,一往无前&#xff01; 1.问题 最近的项目是Python、Java、鸿蒙的来回交叉&#xff0c;再做的一个Java的项目…...

iOS设备投屏Archlinux

我的iphone手机屏太小&#xff0c;我想把手机投到archlinux电脑上看。与是我就想找一个免费的软件。 UxPlay https://github.com/FDH2/UxPlay GPLv3&#xff0c;开源。原来只支持 AirPlay Mirror 协议&#xff0c;现在新增 支持来自 AirPlay 的纯音频 &#xff08;Apple Los…...

如何在 Windows 上安装类似 Synaptic 的 Chocolatey GUI 包管理器

如果你正在寻找类似 Linux 中 APT 的 Windows 包管理器&#xff0c;那么没有什么比 Chocolatey 更好的了。它是 Windows 10 上可用的最佳包管理器之一&#xff0c;可以通过命令行界面安装所有流行的软件和工具。然而&#xff0c;这并不意味着如果你不喜欢命令行&#xff0c;你就…...

Guided Filtering相关记录

一、背景介绍 以前折腾保边滤波时候&#xff0c;刷了一些Guided Filtering相关资料。这里主要是对它们做个算法效果复现和资料简单整理。 二、Guided Filtering 1、基本原理 原版Guided Filtering的提出&#xff0c;主要是为了改善双边滤波做保边平滑滤波器时候的梯度翻转伪影…...

智能AI构建工地安全网:跌倒、抽搐、区域入侵多场景覆盖

智能AI在工地安全中的应用&#xff1a;从监测到救援的全流程实践 一、背景&#xff1a;高温作业下的工地安全挑战 随着夏季高温持续&#xff0c;工地户外作业环境面临严峻考验。工人因高温疲劳、脱水或突发疾病引发的行为异常&#xff08;如晕厥、抽搐、跌倒&#xff09;频发…...

MySQL 8.0 OCP 1Z0-908 121-130题

Q121.Examine these statements and output: mysql> GRANT PROXY ON accountinglocalhost TO ’ ‘ ‘%’; mysql> SELECT USER(), CURRENT_USER(), proxy_user; --------------------------------------------------------- |USER() | CURRENT_USER() | proxy_user I | …...

Spring+LangChain4j小智医疗项目

这里写目录标题 LangChain4j入门配置测试Ollama阿里云百炼平台AIService聊天记忆隔离聊天 MongoDB持久化存储Prompt*创建小智医疗助手Function Calling&#xff08;Tools&#xff09;实战小智医疗智能体 RAGToken分词器向量存储流式输出总结 LangChain4j入门 LangChain4j 是一…...

解决“VMware另一个程序已锁定文件的一部分,进程无法访问“

问题描述 打开VMware里的虚拟机时&#xff0c;弹出"另一个程序已锁定文件的一部分&#xff0c;进程无法访问"如图所示&#xff1a; 这是VM虚拟机的保护机制。虚拟机运行时&#xff0c;为防止数据被篡改&#xff0c;会将所运行的文件保护起来。当虚拟机崩溃或者强制…...

buuctf Crypto-鸡藕椒盐味1

1.题目&#xff1a; 公司食堂最新出了一种小吃&#xff0c;叫鸡藕椒盐味汉堡&#xff0c;售价八块钱&#xff0c;为了促销&#xff0c;上面有一个验证码&#xff0c;输入后可以再换取一个汉堡。但是问题是每个验证码几乎都有错误,而且打印的时候倒了一下。小明买到了一个汉堡&a…...

FreeRTOS的学习记录(基础知识)

FreeRTOS 简介 FreeRTOS 是一个开源的实时操作系统&#xff08;RTOS&#xff09;&#xff0c;专为嵌入式系统设计。它提供了任务管理、时间管理、信号量、消息队列、内存管理等功能&#xff0c;适用于资源受限的微控制器。 FreeRTOS 是一个开源的实时操作系统内核&#xff0c…...

会议分享|高超声速流动测量技术研讨会精彩探析

由中国空气动力学会测控专业委员会主办&#xff0c;中国科学技术大学工程科学学院承办的第八届三次委员会暨高超声速流动测量技术研讨会&#xff0c;5月16日在合肥盛大开幕。 会议专家报告分享了高超声速流动测量的最新研究成果、挑战与突破&#xff0c;展示了PIV高速摄像机、粒…...

1-10 目录树

在ZIP归档文件中&#xff0c;保留着所有压缩文件和目录的相对路径和名称。当使用WinZIP等GUI软件打开ZIP归档文件时&#xff0c;可以从这些信息中重建目录的树状结构。请编写程序实现目录的树状结构的重建工作。 输入格式: 输入首先给出正整数N&#xff08;≤104&#xff09;…...

redis开源协议的变更和使用影响

2013年:采用 BSD 协议 核心内容:Redis 最初采用 BSD 3-Clause 协议,允许用户自由使用、修改和分发代码,包括闭源商业用途。这种宽松的协议促进了 Redis 的快速普及,尤其是云计算厂商将其作为托管服务的基础。 影响:云服务商(如 AWS、阿里云等)可合法地将 Redis 集成到其…...

数据库的锁 - 全局锁、表锁、行锁

目录 一、全局锁 1.1 介绍 1.2 语法 1). 加全局锁 2). 数据备份 3). 释放锁 1.3 特点 二、表级锁 2.1 表锁 2.2 元数据锁&#xff08;MDL&#xff09; 2.3 意向锁 三、行级锁 3.1 行锁​ 3.2 间隙锁 & 临键锁​ 一、全局锁 1.1 介绍 全局锁是对整个数据库实…...

Unix/Linux | A Programming Guide

注&#xff1a;本文为 “UNIX / Linux 教程” 相关文章合辑。 略作重排&#xff0c;如有内容异常&#xff0c;请看原文。 UNIX / Linux Tutorial for Beginners: Learn Online in 7 days By : Emily Carter UpdatedFebruary 5, 2025 UNIX / Linux Tutorial Summary Linux …...

前端——布局方式

普通流&#xff08;标准流&#xff09; 所谓的标准流: 就是标签按照规定好默认方式排列. 1. 块级元素会独占一行&#xff0c;从上向下顺序排列。 常用元素&#xff1a;div、hr、p、h1~h6、ul、ol、dl、form、table 2. 行内元素会按照顺序&#xff0c;从左到右顺序排列&am…...

Multimodal models —— CLIP,LLava,QWen

目录 CLIP CLIP训练 CLIP图像分类 CLIP框架 Text Enocder Image Encoder LLava系列 LLava LLava贡献 LLava模型结构 总结 LLava两阶段训练 LLava 1.5 LLava 1.6 QWen CLIP CLIP是OpenAI 在 2021 年发布的&#xff0c;最初用于匹配图像和文本的预训练神经网络模型…...

Python模块化编程进阶指南:从基础到工程化实践

一、模块化编程核心原理与最佳实践 1.1 模块化设计原则 根据企业级项目实践&#xff0c;模块化开发应遵循以下核心原则&#xff1a; ​​单一职责原则​​&#xff1a;每个模块只承担一个功能域的任务&#xff08;如用户认证模块独立于日志模块&#xff09;​​接口隔离原则…...

json-server的用法-基于 RESTful API 的本地 mock 服务

json-server 是一个非常方便的工具&#xff0c;用于快速搭建基于 RESTful API 的本地 mock 服务&#xff0c;特别适合前端开发阶段模拟后端数据接口。 &#x1f9e9; 一、安装 npm install -g json-server&#x1f680; 二、快速启动 创建一个 db.json 文件&#xff08;模拟数…...