compare local files and remote files.

最近发生了一件怪事,项目在本地run的时候会报一个jar包下找不到某个class的错误,然而同样的project promote到远程服务器上 是ok的,于是就怀疑会不会是远程服务器上的jar包 跟本地的有差别,于是乎写下了这个东西。

 

只是一个basic的版本,可以再加点内容完善的。

 

需要的jar包 

 

连接linux remote server要用的:

ganymed-ssh2.jar

因为我是导出了excel 所以用了POI

poi.jar

 

 

Utils 类

写道
package org.vic.util;

import java.util.Collection;
import java.util.Collections;

public class Utils {

public static <T> Collection<T> ifNullReturnEmpty(Collection<T> collection) {
return collection == null ? Collections.emptyList() : collection;
}

}

 DTO: 数据行结构

 

package org.vic.dto;

public class Row {
	
	private String fileName;
	
	private int fileAmount;

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public int getFileAmount() {
		return fileAmount;
	}

	public void setFileAmount(int fileAmount) {
		this.fileAmount = fileAmount;
	}
	
}

 主功能类:

package org.vic.core;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Font;
import org.vic.dto.Row;
import org.vic.util.Utils;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;

public class Comparator {
	
	/**
	 * 
	 * @param remoteFolderPath 远程服务目标文件夹路径
	 * @param remoteIp         远程服务器IP
	 * @param remoteUsername   远程服务器登陆用户名
	 * @param remotePassword   远程服务器登陆密码
	 * @param localFolderPath  本地目标文件夹路径
	 * @param excelFilePath    导出结果excel文件路径
	 * @throws Exception       抛出一场
	 */
	public void getDifferentFiles(String remoteFolderPath, String remoteIp, String remoteUsername, String remotePassword, String localFolderPath, String excelFilePath) throws Exception {
		System.out.println("start searching local files");
		List<String> localFileNames = getLocalFileNames(localFolderPath);
		System.out.println("start searching remote files");
		List<String> remoteFileNames = getRemoteFileNames(remoteFolderPath, remoteIp, remoteUsername, remotePassword);
		System.out.println("merging data");
		Set<String> totalSet = new HashSet<String>();
		totalSet.addAll(localFileNames);
		totalSet.addAll(remoteFileNames);
		List<Row> localFileInfo = new ArrayList<Row>();
		List<Row> remoteFileInfo = new ArrayList<Row>();
		System.out.println("creating rows");
		for(String fileName : Utils.ifNullReturnEmpty(localFileNames)){
			Row row = fileInfoProcesser(fileName, localFileNames);
			localFileInfo.add(row);
		}
		for(String fileName : Utils.ifNullReturnEmpty(remoteFileNames)){
			Row row = fileInfoProcesser(fileName, remoteFileNames);
			remoteFileInfo.add(row);
		}
		System.out.println("generating excel file...");
		excelCreater(localFileInfo, remoteFileInfo, excelFilePath, totalSet);
		System.out.println("generating finished, please read the file in : " + excelFilePath);
	}
	
	private void excelCreater(List<Row> localList, List<Row> remoteList, String exportFilePath, Set<String> totalSet) {
		HSSFWorkbook wb = new HSSFWorkbook();  
        HSSFSheet sheet = wb.createSheet("comparator"); 
        sheet.setColumnWidth(0, 100 * 180);
        sheet.setColumnWidth(1, 100 * 50);
        sheet.setColumnWidth(2, 100 * 180);
        sheet.setColumnWidth(3, 100 * 50);
        HSSFRow row = sheet.createRow((int) 0);  
        HSSFCellStyle style = wb.createCellStyle();  
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        Font titleFont = wb.createFont();
        titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
        style.setFont(titleFont);
        HSSFCellStyle differentStyle = wb.createCellStyle();
        differentStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        Font font = wb.createFont();
        font.setColor(Font.COLOR_RED);
        differentStyle.setFont(font);
        HSSFCell cell = row.createCell(0);
        cell.setCellValue("localFileName");
        cell.setCellStyle(style);
        cell = row.createCell(1);
        cell.setCellValue("localFileAmount");
        cell.setCellStyle(style);
        cell = row.createCell(2);
        cell.setCellValue("remoteFileName");
        cell.setCellStyle(style);
        cell = row.createCell(3);
        cell.setCellValue("remoteFileAmount");
        cell.setCellStyle(style);
        HSSFCellStyle dataStyle = wb.createCellStyle();  
        dataStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        Font dataFont = wb.createFont();
        dataFont.setColor(HSSFColor.BLUE.index);
        dataStyle.setFont(dataFont);
        List<String> archList = new ArrayList<String>();
        archList.addAll(totalSet);
        for(int i = 0; i < archList.size(); i ++) {
        	row = sheet.createRow(i + 1);  
        	String fileName = archList.get(i);
        	Row localRowData = findRowByFileName(fileName, localList);
        	Row remoteRowData = findRowByFileName(fileName, remoteList);
        	HSSFCell cell0 = row.createCell(0);
        	cell0.setCellStyle(dataStyle);
        	cell0.setCellValue(localRowData.getFileName());
        	HSSFCell cell1 = row.createCell(1);
        	cell1.setCellStyle(dataStyle);
        	cell1.setCellValue(localRowData.getFileAmount());
        	HSSFCell cell2 = row.createCell(2);
        	cell2.setCellStyle(dataStyle);
        	cell2.setCellValue(remoteRowData.getFileName());
        	HSSFCell cell3 = row.createCell(3);
        	cell3.setCellStyle(dataStyle);
        	cell3.setCellValue(remoteRowData.getFileAmount());
            if(!localRowData.getFileName().equals(remoteRowData.getFileName()) || localRowData.getFileAmount() != remoteRowData.getFileAmount()) {
            	cell0.setCellStyle(differentStyle);
            	cell1.setCellStyle(differentStyle);
            	cell2.setCellStyle(differentStyle);
            	cell3.setCellStyle(differentStyle);
            	
            }
        }
        
        try {
        	File file = new File(exportFilePath);
        	if(!file.exists()) {
        		file.createNewFile();
        	}
			FileOutputStream fos = new FileOutputStream(exportFilePath);
			wb.write(fos);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private Row findRowByFileName(String fileName, List<Row> fileList) {
		for(Row row : fileList) {
			if(fileName.equals(row.getFileName())){
				return row;
			}
		}
		Row empty = new Row();
		empty.setFileName("--");
		empty.setFileAmount(0);
		return empty;
	}
	
	private Row fileInfoProcesser(String fileName, List<String> fileList) {
		Row row = new Row();
		int count = 0;
		for(String file : Utils.ifNullReturnEmpty(fileList)) {
			if(file.equals(fileName)) {
				count ++;
			}
		}
		row.setFileName(fileName);
		row.setFileAmount(count);
		return row;
	}
	
	private List<String> getLocalFileNames(String localFolderPath) throws Exception {
		List<String> result = new ArrayList<String>();
		File file = new File(localFolderPath);
		if(file.exists()) {
			if(file.isDirectory()) {
				File[] files = file.listFiles();
				if(file != null && file.length() > 0) {
					for (File subFile : files) {
						String fileName = subFile.getName();
						result.add(fileName);
					}
				}
			} else {
				throw new Exception("path is a file, not a directory!");
			}
		} else {
			throw new Exception("folder is not existing!");
		}
		return result;
	}
	
	private List<String> getRemoteFileNames(String remoteFolderPath, String remoteIp, String remoteUsername, String remotePassword) throws IOException {
		List<String> result = new ArrayList<String>();
		Connection conn = new Connection(remoteIp);
		conn.connect();
        boolean isAuthenticated = conn.authenticateWithPassword(remoteUsername, remotePassword);
        if (isAuthenticated == false) throw new IOException("Authentication failed.");
        Session session = conn.openSession();
        String commands = "cd " + remoteFolderPath + "&&ls";
        session.execCommand(commands);
        InputStream stdout = new StreamGobbler(session.getStdout());
		@SuppressWarnings("resource")
		BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
		String tmp = null;
		while ((tmp = br.readLine()) != null) {
			String fileName = tmp;
			fileName = fileName.replace("Shell Message : ", "");
			result.add(fileName);
		}
        session.close();
        conn.close();
		return result;
	}
	
	/**
	 * Execution Entrance
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		Comparator c = new Comparator();
		
		c.getDifferentFiles("/remoteServer/project/lib", "xx.xx.xx.xx", "username", "password", "local/project/lib", "excel/result.xls");
	}
}

 

 

夸克网盘SVIP技术解析:大文件下载限速原理与开发效率提升 文件下载速度优化是网络存储领域的核心技术挑战。从技术原理层面,网盘服务商通过带宽成本控制、存储架构分层和QoS服务质量策略实现资源合理分配。普通用户下载限速主要基于服务器负载均衡考虑,而SVIP会员通过优先级调度算法获得更好的带宽资源。在开发实践中,大型依赖包下载、数据集分发和开发工具链部署等场景对下载速度有较高要求。通过合理的QoS策略配置,SVIP能够实现真正的不限速下载,让实际速度取决于用户网络环境而非人为限制。这种技术方案特别适合需要频繁处理GB级别模型文件、数据集和开发工具包的AI研究人员和工程师 阅读详情

相关推荐

VSCode Python开发实战配置指南:环境搭建、调试与效率优化

Python开发环境配置是工程落地的第一道关卡,涉及解释器管理、代码格式化、静态检查、交互式计算与调试等核心环节。其本质是构建可复现、可验证、可协作的本地开发流水线。VSCode凭借高度可定制的扩展生态(如Pylance、Black、Flake8、Jupyter)和透明的执行链路,成为兼顾新手友好性与专业深度的首选工具。它能系统性规避解释器混乱、格式化失焦、调试低效等高频痛点,广泛应用于数据分析、Web后端、自动化脚本及机器学习项目。本文聚焦真实场景下的硬核实操,覆盖Windows/macOS/Linux多

381

开源项目RemoteFiles常见问题解决方案

开源项目RemoteFiles常见问题解决方案 一、项目基础介绍 RemoteFiles 是一个开源的 SFTP 客户端,支持 Android 和 iOS 平台。该项目使用了 Flutter 框架,并以 Dart 编程语言进行开发。它提供了一个简洁美观的用户界面,用于管理远程服务器上的文件,包括上传、下载、删除、重命名等操作。 主要编程语言: Dart 二、新手常见问题及解决步骤 问题一:如何配置...

gitblog_00633的博客 519

PyCharm配置Git的三大认知误区与实操闭环

Git是分布式版本控制系统,其核心原理在于本地仓库、暂存区与工作目录构成的三棵树模型,所有操作均围绕对象(commit/tree/blob)和引用(branch/tag)展开。PyCharm作为IDE,并非Git替代品,而是基于Git命令行能力的可视化封装层,其技术价值在于提升日常协作效率,而非屏蔽底层机制。典型应用场景包括高频提交管理、分支可视化合并、冲突图形化解决及本地历史快照恢复。但必须前置完成Git冷启动——即项目根目录下执行git init或git clone生成.git目录,否则PyCharm无

weixin_33709364的博客 480

推荐开源项目:RemoteFiles,跨平台的优雅SFTP客户端

推荐开源项目:RemoteFiles,跨平台的优雅SFTP客户端 ** RemoteFiles ** —— 开源界的一颗新星,为您的移动设备带来了强大而美观的SFTP(Secure File Transfer Protocol)管理体验。无论是Android还是iOS用户,现在都可以通过这一应用轻松地在指尖管理远程服务器上的文件。 项目技术分析 RemoteFiles采用谷歌力推的Flutter...

gitblog_00345的博客 1457

DAGsHub:面向机器学习工作流的数据版本化与实验可复现平台

机器学习项目中的数据版本控制与实验可复现性,是MLOps落地的核心挑战。传统Git无法有效管理大体积数据集,Jupyter缺乏结构化实验追踪能力,导致模型迭代中出现‘参数难追溯、指标难对比、结果难复现’三大痛点。DAGsHub通过深度集成DVC(数据版本控制)、Git(代码版本)和MLflow(实验与指标),构建语义化工作流操作系统,实现数据、代码、参数、模型、指标的原子级绑定与跨维度diff。其核心价值在于将离散的notebook和commit转化为可排序、可比较、可审计的实验快照,并天然支持团队协作、权

weixin_34275734的博客 371

Godot引擎热更新实战:从原理到实现,构建游戏动态更新系统

热更新是一种允许软件在运行时动态更新资源与逻辑,而无需用户重启应用的核心技术。其原理在于将更新内容打包为独立模块,通过版本比对、网络下载与运行时加载,实现对应用内容的动态替换。这项技术的核心价值在于能极大提升线上产品的迭代速度、问题修复效率与运营灵活性,尤其适用于需要频繁更新内容、修复线上Bug或开展运营活动的游戏与实时应用场景。在游戏开发领域,Godot引擎因其开源、轻量而备受青睐,但其原生并未提供开箱即用的热更新方案。本文聚焦于Godot引擎,深入探讨如何利用其资源包(.pck)加载机制,构建一套涵盖版

weixin_30595035的博客 447

RemoteFiles 开源项目安装与使用教程

RemoteFiles 开源项目安装与使用教程 一、项目目录结构及介绍 RemoteFiles 是一个基于 GitHub 的开源项目,旨在实现远程文件管理与同步功能。以下是该项目的目录结构概览及其简要说明: RemoteFiles/ ├── src # 源代码主目录 │ ├── main # 主程序逻辑所在目录 │ │ ...

gitblog_00772的博客 500

告别Source Insight!手把手教你用VSCode配置C/C++高亮主题(附完整JSON)

本文详细介绍了如何从Source Insight迁移到VSCode,打造专业级C/C++开发环境。通过精选字体、深度定制语法高亮、优化代码导航和配置高效工作流,VSCode不仅能复刻Source Insight的体验,还能提供更现代的插件生态和远程开发能力。附完整JSON配置,助你无缝过渡。

dianan0938的博客 328

【亲测免费】 RemoteFiles:一款开源的SFTP客户端

RemoteFiles:一款开源的SFTP客户端 RemoteFiles 是一个开源的 SFTP 客户端,适用于 Android 和 iOS 系统。该项目使用 Flutter 框架,并以 Dart 编程语言进行开发。 核心功能 该项目的核心功能包括: 文件管理:上传和下载文件、删除文件/文件夹、重命名文件/文件夹、复制和移动文件和文件夹到服务器上的其他位置、分享文件、无需在设备上永久保存即可打开...

gitblog_00534的博客 669

PyCharm 2024.3 远程开发配置:3步实现 SSH + Anaconda 环境同步与自动上传

本文详细介绍了如何在PyCharm 2024.3中配置SSH远程开发环境,实现与Anaconda环境的同步与自动上传。通过3个简单步骤,开发者可以轻松搭建高效的云端Python开发环境,提升工作效率和团队协作体验。文章还提供了常见问题解决方案和性能优化建议,帮助开发者充分利用PyCharm的远程开发功能。

weixin_33709590的博客 575

移动机器人底盘-四轮差速模型(四轮独立)

对于底盘的前轮和后轮来说,其速度是同步的,那么在理想条件下,可以将底盘运动视为以ICR为圆心做圆周运动,对于四个轮子来说,圆周运动的角速度是一致的,圆周运动圆心ICR始终位于底盘几何中心COG的y轴延长线上,ICR与COG之间的距离。有关,整个底盘的速度位于速度瞬心COM处,用。四轮差速底盘设定左轮、右轮得速度分别为。圆周运动的角速度公式如式1所示。受约束,约束与圆周运动的角速度。合成,设四个轮子的速度分别为。,设左轮和右轮之间的轴距为。为圆周运动角速度,线速度为。,其均由预设目标速度。

Moresweet 猫甜 1万+

百度云盘文件操作使用总结

百度云盘文件操作使用总结使用示例官方文档步骤遇到的问题跟解决方法 使用示例 使用百度开放平台的接口已经很多次,以下是百度网盘文件操作的使用经历 官方文档步骤 我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客: 首先注册开发者账号 文件操作接口需要获取用户token 操作步骤地址; 文件操作文档 点基础能力; 遇到的问题跟解决方法 文件操作 新目录不对 使用了move操作 幸好之前保留了旧目录的信息,基本上文件的

qq_42401192的博客 986

训练集、验证集、测试集!YOLO系列标签数量统计!

【代码】训练集、验证集、测试集!YOLO系列标签数量统计!

qq_26281057的博客 652

CANN/cannbot-skills智能体观测工具

Session-level observability tool for LLM coding agents. Helps analyze long-context usage patterns, detect model hallucination issues, and govern context window growth across agent sessions. **[中文文档](

gitblog_00146的博客 866

从零到一:华为iMaster NCE-Campus部署中的Euler OS与FusionInsight深度解析

本文深入解析华为iMaster NCE-Campus部署中Euler OS与FusionInsight的关键技术要点,包括RAID配置、网络绑定技术、安装避坑指南及性能调优方案。通过实战经验和详细配置示例,帮助工程师提升部署效率与系统稳定性,确保华为企业级解决方案的高效运行。

f6g7h8i9j的博客 550

Kubernetes多网卡环境下Calico网络配置避坑指南:如何精准指定业务网卡

本文针对Kubernetes多网卡环境下Calico网络配置的常见痛点,提供了精准指定业务网卡的实战指南。通过深入分析Calico的IP自动检测机制,详细解读并对比了五种IP_AUTODETECTION_METHOD配置方法(如interface、cidr、can-reach等),帮助运维人员从根源上解决网络分区和Pod通信失败问题,确保生产集群网络的稳定与可靠。

weixin_28835551的博客 731

Git命令

git命令

weixin_48120109的博客 7513

从TM1到TM9:手把手教你用Wireshark抓包分析LTE下行调度与传输模式切换

本文详细解析了如何使用Wireshark抓包分析LTE下行调度中的传输模式切换,从TM1到TM9的动态调整过程。通过实战案例,包括小区边缘移动、高速场景和多用户调度,揭示eNodeB如何基于信道质量指标(如RSRP、SINR)动态切换传输模式,并提供关键信令解析和优化建议,助力网络工程师提升LTE网络性能。

weixin_42651748的博客 317

维护源码检出:构建可验证、可追溯、可回滚的代码快照体系

源码检出(source checkout)是软件交付链路中保障代码状态确定性的基础环节,其本质远超简单的 git pull 操作,涉及 Git 分支同步、子模块管理、浅克隆处理、工作区洁净性控制等核心原理。在 CI/CD、GitOps 和容器化部署场景下,checkout 状态失准将直接导致构建不一致、镜像版本混乱、生产回滚失败等严重问题。通过引入 commit 哈希校验、submodule 递归更新、深度克隆策略及多层运行时验证机制,可系统性提升代码加载的可信度与可观测性。本文聚焦于企业级工程实践中‘ma

weixin_34343308的博客 447

即梦AI使用教程

摘要: 即梦AI是字节跳动推出的多模态AI创作平台,整合图片、视频、智能编辑功能,基于OmniHuman模型支持中英日三语操作。核心特点包括: 技术升级:4.0版本强化中文语义理解与微观表现力,新增故事分镜生成; 创作功能:支持文本/图片转视频、AI对口型、商业级抠图与多图层融合; 用户友好:移动/网页双端适配,灵感社区复用提示词,剪映生态无缝衔接; 应用场景:覆盖电商换装、虚拟主播、设计融合等需求,未来将开放API拓展生态。 (字数:149)

专业深耕,技术前沿 6325

RK3588与FocalTech触摸屏代码适配全解析:从原理到实战

摘要:本文详细介绍了瑞芯微RK3588处理器与FocalTech触摸屏的适配过程,包括硬件特性、驱动加载、设备树配置和常见问题解决方案。RK3588作为8nm工艺的高性能处理器,具备强大的计算能力和丰富的接口资源;FocalTech触摸屏则采用电容式技术,支持I2C/SPI接口。适配关键步骤包括驱动程序加载、硬件连接检查、设备树配置和内核版本兼容性处理,并提供了代码示例和问题排查方法。随着嵌入式设备智能化发展,该适配技术将持续优化,为智能交互提供更优解决方案。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 273

Git操作

Git1.Git总结2.Git常用命令流程图3.Git分布式版本控制的管理方式图4.Git的常见命令5.GitFlow的工作流(企业如何使用Git) 1.Git总结 2.Git常用命令流程图 3.Git分布式版本控制的管理方式图 4.Git的常见命令 git init :初始化好一个本地的库 git add . :添加当前目录的所有文件到暂存区 git commit -m '提示信息' :......

weixin_43766298的博客 382

MCAL知识点(十):ERU驱动配置详解

ERS:外部请求单元ETL:中断逻辑单元OGU:输出逻辑单元MCU里面配置要使用的功能和选择输入的管脚,注意上述模块关注点讲述的ERU必须和边沿检测模块相关联。

梦想技术家 1224

一个**带自动更新功能的 Python 应用框架**。展示了一套完整的轻量级更新方案:应用启动时自动检查远程版本,如有新版本则下载、解压、替换自身并重启。

**ZIP 包内容**:`new_version.zip` 内应包含**完整的新版应用文件**,更新时会替换掉当前目录下除了 `new_version.zip`、`new_version/` 和更新脚本以外的所有内容。1. 将 `main.py`、`updater.py`、`log.py`、`version.json` 放在**同一目录**下(例如 `myapp/`)。- **版本号格式**:必须为 `x.y.z` 数字格式,比较时转为元组,其他格式会被视为 `0.0.0`。

m0_73462935的博客 501

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Prometheus 3.0架构深度解析:云原生监控系统的四层演进与最佳实践

Prometheus作为云原生监控的事实标准,其3.0版本带来了革命性的架构演进与性能突破。本文将深度解析Prometheus 3.0的四层架构设计、原生直方图优化、OTLP协议支持等核心特性,并提供实战部署方案与性能调优指南。无论您是技术决策者还是架构师,都能从中获得构建高效监控系统的关键洞察。🚀 ## 引言:云原生监控的挑战与演进 在微服务和容器化架构成为主流的今天,监控系统面临着前所未

gitblog_00929的博客 582

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

git - study

progit 这本书是官方的,权威。以下内容都是对这本书的读书笔记和实验的体会。这本官方的书,前半部分说git命令具体怎么用,后半部分说github怎么用 + git高级和细节的操作。因为作者就是github的人。能看完前半部分对自己有用的部分,就可以熟练用git命令来进行日常的git操作了。对于危险的git操作(e.g. 删除本地分支,删除远程分支,删除tag, rebase, reset), 最好不要做。如果非要做的话,最好找个靠谱的GUI工具来弄。

博客标题不能为空 1546
上一篇: Servlet 3.0 使用request.part 处理文件上传
下一篇: 设计模式
vortex331
博客等级 码龄16年 0粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值