Unity 位图字体
下载Bitmap Font Generator
BMFont - AngelCode.com
解压后不用安装直接双击使用
提前设置
1、设置Bit depth为32
Options->Export options
2、清空所选字符
因为我们将在后边导入需要的字符。
Edit->Select all chars 先选择所有字符
Edit->Clear all chars in font 再清空所有字符
配置字符
1、打开Open Image Manager
Edit->Open Image Manager
2、配置字符和对应的字符图片
先准备这些字符的ASCII码
可以通过在线工具查询:ASCII编码转换,ASCII码在线查询工具
字符 | ASCII码 |
0 | 48 |
1 | 49 |
2 | 50 |
3 | 51 |
4 | 52 |
5 | 53 |
6 | 54 |
7 | 55 |
8 | 56 |
9 | 57 |
. | 46 |
+ | 43 |
- | 45 |
K | 75 |
M | 77 |
G | 71 |
点击Image->Import image,开始配置
返回主界面,查看标有小亮点的字符为已配置成功的字符
导出文件
导出前可以预览一下 Options->Visualize
直接导出
Options->Save bitmap font as....
导出成功
导入Unity使用
创建下面两个脚本,将其放到Editor文件夹下
using UnityEngine;
using UnityEditor;
using System;
using System.IO;public class BFImporter : AssetPostprocessor
{static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths){foreach (string str in importedAssets){DoImportBitmapFont(str);}foreach (string str in deletedAssets){DelBitmapFont(str);}for (var i = 0; i < movedAssets.Length; i++){MoveBitmapFont(movedFromAssetPaths[i], movedAssets[i]);}}public static bool IsFnt(string path){return path.EndsWith(".fnt", StringComparison.OrdinalIgnoreCase);}public static void DoImportBitmapFont(string fntPath){if (!IsFnt(fntPath)) return;TextAsset fnt = AssetDatabase.LoadMainAssetAtPath(fntPath) as TextAsset;string text = fnt.text;FntParse parse = FntParse.GetFntParse(ref text);if (parse == null) return;string fntName = Path.GetFileNameWithoutExtension(fntPath);string rootPath = Path.GetDirectoryName(fntPath);string fontPath = string.Format("{0}/{1}.fontsettings", rootPath, fntName);Texture2D[] textures = DoImportTextures(parse, rootPath, fnt);if (textures.Length > 1){Debug.LogError(fntPath + " has more than one texture!");}Font font = AssetDatabase.LoadMainAssetAtPath(fontPath) as Font;if (font == null){font = new Font();AssetDatabase.CreateAsset(font, fontPath);AssetDatabase.WriteImportSettingsIfDirty(fontPath);AssetDatabase.ImportAsset(fontPath);}Material material = AssetDatabase.LoadAssetAtPath(fontPath, typeof(Material)) as Material;if (material == null){material = new Material(Shader.Find("UI/Default"));material.name = "Font Material";AssetDatabase.AddObjectToAsset(material, fontPath);// unity 5.4+ cannot refresh it immediately, must import itAssetDatabase.ImportAsset(fontPath);}font.material = material;material.mainTexture = textures[0];font.characterInfo = parse.charInfos;SerializedObject so = new SerializedObject(font);so.Update();so.FindProperty("m_FontSize").floatValue = Mathf.Abs(parse.fontSize);so.FindProperty("m_LineSpacing").floatValue = parse.lineHeight;so.FindProperty("m_Ascent").floatValue = parse.lineBaseHeight;SerializedProperty prop = so.FindProperty("m_Descent");if (prop != null)prop.floatValue = parse.lineBaseHeight - parse.lineHeight;UpdateKernings(so, parse.kernings);so.ApplyModifiedProperties();so.SetIsDifferentCacheDirty();AssetDatabase.DeleteAsset(fntPath);AssetDatabase.SaveAssets();// unity 5.5 can not load custom fontReloadFont(fontPath);}private static Texture2D[] DoImportTextures(FntParse parse, string rootPath, TextAsset fnt){int len = parse.textureNames.Length;Texture2D[] textures = new Texture2D[len];for (int i = 0; i < len; i++){string texPath = string.Format("{0}/{1}", rootPath, parse.textureNames[i]);Texture2D texture = AssetDatabase.LoadMainAssetAtPath(texPath) as Texture2D;if (texture == null){Debug.LogErrorFormat(fnt, "{0}: not found '{1}'.", typeof(BFImporter), texPath);return textures;}TextureImporter texImporter = AssetImporter.GetAtPath(texPath) as TextureImporter;texImporter.textureType = TextureImporterType.GUI;texImporter.mipmapEnabled = false;texImporter.SaveAndReimport();textures[i] = texture;}return textures;}private static void UpdateKernings(SerializedObject so, Kerning[] kernings){int len = kernings != null ? kernings.Length : 0;SerializedProperty kerningsProp = so.FindProperty("m_KerningValues");if (len == 0){kerningsProp.ClearArray();return;}int propLen = kerningsProp.arraySize;for (int i = 0; i < len; i++){if (propLen <= i){kerningsProp.InsertArrayElementAtIndex(i);}SerializedProperty kerningProp = kerningsProp.GetArrayElementAtIndex(i);kerningProp.FindPropertyRelative("second").floatValue = kernings[i].amount;SerializedProperty pairProp = kerningProp.FindPropertyRelative("first");pairProp.Next(true);pairProp.intValue = kernings[i].first;pairProp.Next(false);pairProp.intValue = kernings[i].second;}for (int i = propLen - 1; i >= len; i--){kerningsProp.DeleteArrayElementAtIndex(i);}}private static void DelBitmapFont(string fntPath){if (!IsFnt(fntPath)) return;string fontPath = fntPath.Substring(0, fntPath.Length - 4) + ".fontsettings";AssetDatabase.DeleteAsset(fontPath);}private static void MoveBitmapFont(string oldFntPath, string nowFntPath){if (!IsFnt(nowFntPath)) return;string oldFontPath = oldFntPath.Substring(0, oldFntPath.Length - 4) + ".fontsettings";string nowFontPath = nowFntPath.Substring(0, nowFntPath.Length - 4) + ".fontsettings";AssetDatabase.MoveAsset(oldFontPath, nowFontPath);}// new font can not display via Text in unity 5.5// must import import itprivate static void ReloadFont(string fontPath){var tmpPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());AssetDatabase.ExportPackage(fontPath, tmpPath);AssetDatabase.DeleteAsset(fontPath);var startTime = DateTime.Now;EditorApplication.CallbackFunction func = null;func = () =>{TimeSpan dalt = DateTime.Now - startTime;if (dalt.TotalSeconds >= 0.1){EditorApplication.update -= func;AssetDatabase.ImportPackage(tmpPath, false);File.Delete(tmpPath);}};EditorApplication.update += func;}
}
using UnityEngine;
using System.Xml;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;public struct Kerning
{public int first;public int second;public int amount;
}public class FntParse
{public int textureWidth;public int textureHeight;public string[] textureNames;public string fontName;public int fontSize;public int lineHeight;public int lineBaseHeight;public CharacterInfo[] charInfos { get; private set; }public Kerning[] kernings { get; private set; }public static FntParse GetFntParse(ref string text){FntParse parse = null;if (text.StartsWith("info")){parse = new FntParse();parse.DoTextParse(ref text);}else if (text.StartsWith("<")){parse = new FntParse();parse.DoXMLPase(ref text);}return parse;}#region xmlpublic void DoXMLPase(ref string content){XmlDocument xml = new XmlDocument();xml.LoadXml(content);XmlNode info = xml.GetElementsByTagName("info")[0];XmlNode common = xml.GetElementsByTagName("common")[0];XmlNodeList pages = xml.GetElementsByTagName("pages")[0].ChildNodes;XmlNodeList chars = xml.GetElementsByTagName("chars")[0].ChildNodes;fontName = info.Attributes.GetNamedItem("face").InnerText;fontSize = ToInt(info, "size");lineHeight = ToInt(common, "lineHeight");lineBaseHeight = ToInt(common, "base");textureWidth = ToInt(common, "scaleW");textureHeight = ToInt(common, "scaleH");int pageNum = ToInt(common, "pages");textureNames = new string[pageNum];for (int i = 0; i < pageNum; i++){XmlNode page = pages[i];int pageId = ToInt(page, "id");textureNames[pageId] = page.Attributes.GetNamedItem("file").InnerText;}charInfos = new CharacterInfo[chars.Count];for (int i = 0; i < chars.Count; i++){XmlNode charNode = chars[i];charInfos[i] = CreateCharInfo(ToInt(charNode, "id"),ToInt(charNode, "x"),ToInt(charNode, "y"),ToInt(charNode, "width"),ToInt(charNode, "height"),ToInt(charNode, "xoffset"),ToInt(charNode, "yoffset"),ToInt(charNode, "xadvance"),ToInt(charNode, "page"));}// kerningsXmlNode kerningsNode = xml.GetElementsByTagName("kernings")[0];if (kerningsNode != null && kerningsNode.HasChildNodes){XmlNodeList kerns = kerningsNode.ChildNodes;kernings = new Kerning[kerns.Count];for (int i = 0; i < kerns.Count; i++){XmlNode kerningNode = kerns[i];kernings[i] = new Kerning();kernings[i].first = ToInt(kerningNode, "first");kernings[i].second = ToInt(kerningNode, "second");kernings[i].amount = ToInt(kerningNode, "amount");}}}private static int ToInt(XmlNode node, string name){return int.Parse(node.Attributes.GetNamedItem(name).InnerText);}#endregion#region textprivate Regex pattern;public void DoTextParse(ref string content){// letter=" " // \S+=".+?"// letter="x" // \S+=".+?"// letter=""" // \S+=".+?"// letter="" // \S+// char // \S+pattern = new Regex(@"\S+="".+?""|\S+");string[] lines = content.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);ReadTextInfo(ref lines[0]);ReadTextCommon(ref lines[1]);for (int j = 0; j < textureNames.Length; j++){ReadTextPage(ref lines[j + 2]);}// don't use count of chars, count is incorrect if has space //ReadTextCharCount(ref lines[3]);List<CharacterInfo> list = new List<CharacterInfo>();int i = 2 + textureNames.Length;int l = lines.Length;for (; i < l; i++){if (!ReadTextChar(i - 4, ref lines[i], ref list))break;}charInfos = list.ToArray();// skip empty linefor (; i < l; i++){if (lines[i].Length > 0)break;}// kerningsif (i < l){int count = 0;if (ReadTextCount(ref lines[i++], out count)){int start = i;kernings = new Kerning[count];for (; i < l; i++){if (!ReadTextKerning(i - start, ref lines[i], ref list))break;}};}}private void ReadTextInfo(ref string line){string[] keys;string[] values;SplitParts(line, out keys, out values);for (int i = keys.Length - 1; i >= 0; i--){switch (keys[i]){case "face": fontName = values[i]; break;case "size": fontSize = int.Parse(values[i]); break;}}}private void ReadTextCommon(ref string line){string[] keys;string[] values;SplitParts(line, out keys, out values);for (int i = keys.Length - 1; i >= 0; i--){switch (keys[i]){case "lineHeight": lineHeight = int.Parse(values[i]); break;case "base": lineBaseHeight = int.Parse(values[i]); break;case "scaleW": textureWidth = int.Parse(values[i]); break;case "scaleH": textureHeight = int.Parse(values[i]); break;case "pages": textureNames = new string[int.Parse(values[i])]; break;}}}private void ReadTextPage(ref string line){string[] keys;string[] values;SplitParts(line, out keys, out values);string textureName = null;int pageId = -1;for (int i = keys.Length - 1; i >= 0; i--){switch (keys[i]){case "file": textureName = values[i]; break;case "id": pageId = int.Parse(values[i]); break;}}textureNames[pageId] = textureName;}private bool ReadTextCount(ref string line, out int count){string[] keys;string[] values;SplitParts(line, out keys, out values);count = 0;for (int i = keys.Length - 1; i >= 0; i--){switch (keys[i]){case "count":count = int.Parse(values[i]);return true;}}return false;}private bool ReadTextChar(int idx, ref string line, ref List<CharacterInfo> list){if (!line.StartsWith("char")) return false;string[] keys;string[] values;SplitParts(line, out keys, out values);int id = 0, x = 0, y = 0, w = 0, h = 0, xo = 0, yo = 0, xadvance = 0;for (int i = keys.Length - 1; i >= 0; i--){switch (keys[i]){case "id": id = int.Parse(values[i]); break;case "x": x = int.Parse(values[i]); break;case "y": y = int.Parse(values[i]); break;case "width": w = int.Parse(values[i]); break;case "height": h = int.Parse(values[i]); break;case "xoffset": xo = int.Parse(values[i]); break;case "yoffset": yo = int.Parse(values[i]); break;case "xadvance": xadvance = int.Parse(values[i]); break;}}list.Add(CreateCharInfo(id, x, y, w, h, xo, yo, xadvance));return true;}private bool ReadTextKerning(int idx, ref string line, ref List<CharacterInfo> list){if (!line.StartsWith("kerning")) return false;string[] keys;string[] values;SplitParts(line, out keys, out values);Kerning kerning = new Kerning();for (int i = keys.Length - 1; i >= 0; i--){switch (keys[i]){case "first": kerning.first = int.Parse(values[i]); break;case "second": kerning.second = int.Parse(values[i]); break;case "amount": kerning.amount = int.Parse(values[i]); break;}}kernings[idx] = kerning;return true;}private bool SplitParts(string line, out string[] keys, out string[] values){MatchCollection parts = pattern.Matches(line);int count = parts.Count;keys = new string[count - 1];values = new string[count - 1];for (int i = count - 2; i >= 0; i--){string part = parts[i + 1].Value;int pos = part.IndexOf('=');keys[i] = part.Substring(0, pos);values[i] = part.Substring(pos + 1).Trim('"');}return true;}#endregionprivate CharacterInfo CreateCharInfo(int id, int x, int y, int w, int h, int xo, int yo, int xadvance, int page = 0){Rect uv = new Rect();uv.x = (float)x / textureWidth + page;uv.y = (float)y / textureHeight;uv.width = (float)w / textureWidth;uv.height = (float)h / textureHeight;uv.y = 1f - uv.y - uv.height;Rect vert = new Rect();vert.x = xo;
#if UNITY_5_0 || UNITY_5_1 || UNITY_5_2// unity 5.0 can not support baseline for vert.y = yo;
#elsevert.y = yo - lineBaseHeight;
#endifvert.width = w;vert.height = h;vert.y = -vert.y;vert.height = -vert.height;CharacterInfo charInfo = new CharacterInfo();charInfo.index = id;#if UNITY_5_3_OR_NEWER || UNITY_5_3 || UNITY_5_2charInfo.uvBottomLeft = new Vector2(uv.xMin, uv.yMin);charInfo.uvBottomRight = new Vector2(uv.xMax, uv.yMin);charInfo.uvTopLeft = new Vector2(uv.xMin, uv.yMax);charInfo.uvTopRight = new Vector2(uv.xMax, uv.yMax);charInfo.minX = (int)vert.xMin;charInfo.maxX = (int)vert.xMax;charInfo.minY = (int)vert.yMax;charInfo.maxY = (int)vert.yMin;charInfo.bearing = (int)vert.x;charInfo.advance = xadvance;
#else
#pragma warning disable 618charInfo.uv = uv;charInfo.vert = vert;charInfo.width = xadvance;
#pragma warning restore 618
#endifreturn charInfo;}
}
将这两个文件直接拖入Unity中,系统自动生成字体文件
直接使用
相关文章:

Unity 位图字体
下载Bitmap Font Generator BMFont - AngelCode.com 解压后不用安装直接双击使用 提前设置 1、设置Bit depth为32 Options->Export options 2、清空所选字符 因为我们将在后边导入需要的字符。 Edit->Select all chars 先选择所有字符 Edit->Clear all chars i…...
科技快讯 | DeepSeek推出NSA加速长上下文训练,xAI Grok系列将陆续开源,月之暗面发布Kimi Latest新模型
阶跃星辰首次开源Step系列多模态大模型 2月18日,财联社消息,阶跃星辰与吉利汽车集团宣布,双方合作开发的阶跃Step系列多模态大模型向全球开发者开源。包括参数量达300亿的Step-Video-T2V视频生成模型和行业内首款产品级开源语音交互大模型Ste…...

网络安全 | 5G网络安全:未来无线通信的风险与对策
网络安全 | 5G网络安全:未来无线通信的风险与对策 一、前言二、5G 网络的技术特点2.1 超高速率与低延迟2.2 大容量连接与网络切片三、5G 网络面临的安全风险3.1 网络架构安全风险3.2 设备终端安全风险3.3 应用场景安全风险3.4 用户隐私安全风险四、5G 网络安全对策4.1 强化网络…...

Linux 实操篇 组管理和权限管理、定时任务调度、Linux磁盘分区和挂载
一、组管理和权限管理 (1)Linux组基本介绍 在linux中的每个用户必须属于一个组,不能独立于组外 在linux中每个文件有所有者、所在组、其他组的概念 (2)文件/目录 所有者 一般为文件的创建者,谁创建了该…...

应用案例 | uaGate SI助力汽车零部件工厂将生产数据传输到MES
一、背景和挑战 (图1 汽车零部件工厂生产车间) 随着汽车工业的不断发展,新能源汽车市场的竞争日益激烈,这对汽车零部件供应商提出了更高的要求,包括提升产品精度、增强可靠性、节能环保以及控制成本等多个方面。某国际…...

Android JNI的理解与使用。
写在前面:Java相对于C/C来说是更高级的语言,隐藏了指针,可读性更高,更容易学习,但是无法直接操作硬件、运行速度较慢也是不可回避的硬伤。JNI就是Java官方定义的一套标准“接口”,用于Java和C/C之间互相调用…...

fpga助教面试题
第一题 module sfp_pwm( input wire clk, //clk is 200M input wire rst_n, input wire clk_10M_i, input wire PPS_i, output reg pwm ) reg [6:0] cunt ;always (posedge clk ) beginif(!rst_n)cunt<0;else if(cunt19) //200M是10M的20倍cunt<0;elsecunt<cunt1;…...
Git命令详解与工作流介绍:全面掌握版本控制系统的操作指南
Git Git是一个版本控制系统(也称为源代码控制系统),允许程序员和其他处理文本文件的人在独立工作时协调更改。Git还支持二进制资产,如图片,但这些格式不支持逐行版本管理,这使得版本控制真正强大。 Git概…...
提升信息检索准确性和效率的搜索技巧
一、基础技巧 精准关键词 避免长句子,提取核心关键词(如用“光合作用 步骤”代替“请告诉我光合作用的具体过程”)。 同义词替换:尝试不同表达(如“AI 发展史” vs “人工智能 历史”)。 排除干扰词 使用…...
Qt 中使用 ffmpeg 获取采集卡数据录制视频
作者:billy 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 前言 之前做了一个功能,从采集卡获取数据然后录制成视频,结果发现录制的视频内存占用非常大,1分钟的…...
Python爬虫TLS
TLS指纹校验原理和绕过 浏览器可以正常访问,但是用requests发送请求失败。 后端是如何监测得呢?为什么浏览器可以返回结果,而requests模块不行呢? https://cn.investing.com/equities/amazon-com-inc-historical-data 1.指纹校…...

【Linux AnolisOS】配置Linux固定ip地址。然后在Windows上连接使用linux中docker容器里的redis和nacos。
1.关于将虚拟机ip地址更改为静态地址 ,跟着下面这个视频搞的,不想看文章的可以看视频。 第四章-07-配置Linux固定IP地址哔哩哔哩bilibili 当用的centos9 视频里让我们打开网络配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33 但是我打开时…...

IDEA中查询Maven项目的依赖树
在Maven项目中,查看项目的依赖树是一个常见的需求,特别是当你需要了解项目中直接或间接依赖了哪些库及其版本时。你可以通过命令行使用Maven的dependency:tree插件来做到这一点。这个命令会列出项目中所有依赖的树状结构。 打开idea项目的终端ÿ…...

【Ubuntu】GPU显存被占用,但显示没有使用GPU的进程
文章目录 一、问题描述二、解决方案2.1 寻找问题进程2.2 尝试杀死相关进程2.3 投放核弹,一键全杀2.4 再次查看GPU使用情况 参考资料 一、问题描述 今天使用服务器的时候发现gpu被占了很多内存,但是使用 nvidia-smi 命令并没有发现占这么多显存的进程&am…...

【并发编程】Java并发编程核心包
1、简介 java.util.concurrent 是 Java 并发编程的核心包,提供了丰富的工具和框架来支持多线程编程、并发任务执行、线程安全集合、同步机制等。 2、线程池Thread Pool 线程池是并发编程中最重要的工具之一,用于管理和复用线程,避免频繁创…...
Unity 淡入淡出
淡入(Fade in):类似打开幕布 淡出(Fade out):类似关上幕布 方案一 使用Dotween(推荐) using DG.Tweening; using UnityEngine; using UnityEngine.UI;public class Test : MonoB…...

完整的 LoRA 模型训练步骤:如何使用 Kohya_ss 进行 LoRA 训练
完整的 LoRA 模型训练步骤:如何使用 Kohya_ss 进行 LoRA 训练 一、环境配置1. 安装 Python 和虚拟环境2. 克隆 Kohya_ss 仓库3. 安装依赖4. 启动 GUI lora训练1. 准备数据 图片处理打标签2. 配置 LoRA 训练2.2 配置图片文件夹和输出目录 训练解决方法: 使…...

视觉分析之边缘检测算法
9.1 Roberts算子 Roberts算子又称为交叉微分算法,是基于交叉差分的梯度算法,通过局部差分计算检测边缘线条。 常用来处理具有陡峭的低噪声图像,当图像边缘接近于正45度或负45度时,该算法处理效果更理想。 其缺点是对边缘的定位…...

git输错用户名或者密码
git push时候跳出window弹窗,输入用户名和密码,如果错误,会有如下情况: $ git push -u origin “master” remote: [session-6c466aa6] rain: Incorrect username or password (access token) fatal: Authentication failed for ‘…...

【Unity Shader编程】之图元装配与光栅化
执行方式:自动完成 图元装配自动化流程 顶点坐标存入装配区 → 按绘制模式连接顶点 → 生成完整几何图元 示例:gl.drawArrays(gl.TRIANGLES, 0, 3)自动生成三角形 会自动自动裁剪超出屏幕范围(NDC空间外)的三角形,仅保…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...

解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...