#
杂项技术
背景
我们有的时候只是涉及到一些小文件,比如一些配置文件,一些小的图片等等,这些文件的内容不是很大,但是我们又不想直接把这些文件放到项目中,这个时候我们可以使用链接来直接存储这些小文件的内容。
而url支持使用 data
协议来使用base64格式直接存储小文件的内容,这样我们就可以直接使用链接来存储小文件的内容。
使用
我们可以使用如下的方式来存储小文件的内容:
1
| <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAA/0lEQVQ4jZXTsUoDQRDG8d8Q9" alt="Red dot" />
|
这里的
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAA/0lEQVQ4jZXTsUoDQRDG8d8Q9
就是一个base64格式的图片内容,我们可以直接使用这个链接来展示图片。
然后我写了一个简单的脚本来生成base64格式的图片内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
| #include <fstream> #include <vector> #include <string> #include <iostream>
const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/";
#include <chrono>
std::string base64_encode(const std::vector<unsigned char>& buffer) { std::string encoded; int i = 0; int j = 0; unsigned char char_array_3[3]; unsigned char char_array_4[4];
int totalBytes = buffer.size(); int progressInterval = totalBytes / 10;
for (const auto& byte : buffer) { char_array_3[i++] = byte; if (i == 3) { char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f;
for (i = 0; (i < 4); i++) encoded += base64_chars[char_array_4[i]]; i = 0;
if (encoded.size() % progressInterval == 0) { int progress = (encoded.size() * 100) / totalBytes; std::cout << "Progress: " << progress << "%" << std::endl; } } }
if (i) { for (j = i; j < 3; j++) char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
for (j = 0; (j < i + 1); j++) encoded += base64_chars[char_array_4[j]];
while ((i++ < 3)) encoded += '='; }
return encoded; }
void fileToBase64(const std::string& path) { std::ifstream file(path, std::ios::binary); std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(file), {});
std::string base64 = base64_encode(buffer); std::string dataUrl = "data:application/x-rar-compressed;base64," + base64;
std::string::size_type iPos = path.find_last_of('\\') + 1; std::string fileName = path.substr(iPos, path.length() - iPos); std::cout << fileName << std::endl; std::string fileNameWithoutExtension = fileName.substr(0, fileName.rfind(".")); std::cout << fileNameWithoutExtension << std::endl; std::string suffix_str = fileName.substr(fileName.find_last_of('.') + 1); std::cout << suffix_str << std::endl;
std::string outputFileName = "downloadLink_" + fileNameWithoutExtension + ".md"; std::ofstream output(outputFileName); output << "---" << std::endl; output << "title: " << fileName << std::endl; output << "date: 2024-03-01 17:36" << std::endl; output << "mathjax: false" << std::endl; output << "tags:" << std::endl; output << " - Download" << std::endl; output << "---" << std::endl; output << "<a href=\"" << dataUrl << "\" download=\""<< fileName <<"\">点击下载</a>"; output.close();
std::string outputFileName2 = "downloadLink_" + fileNameWithoutExtension + ".md"; std::ofstream output2("DownloadLink\\" + outputFileName2); output2 << "---" << std::endl; output2 << "title: " << fileName << std::endl; output2 << "mathjax: false" << std::endl; output2 << "date: 2024-03-01 17:36" << std::endl; output2 << "tags:" << std::endl; output2 << " - Download" << std::endl; output2 << "---" << std::endl; output2.close();
std::cout << "Output file: " << outputFileName << std::endl; }
int main(int argc, char* argv[]) { if (argc < 2) { std::cout << "Usage: " << argv[0] << " file1 [file2] [file3] ..." << std::endl; return 1; } for (int i = 1; i < argc; i++){ std::cout << "Processing " << argv[i] << "..." << std::endl; fileToBase64(argv[i]); }
std::cout << "Press any key to exit..." << std::endl; std::cin.get(); return 0; }
|
这个脚本可以将指定的文件转换为base64格式的内容,并且生成一个md文件,这个md文件包含了下载链接,我们可以直接使用这个md文件来展示下载链接。
下面就是一个使用这个脚本生成的md文件的例子:
1 2 3 4 5 6 7 8
| --- title: test.rar date: 2024-03-01 17:36 mathjax: false tags: - Download --- <a href="data:application/x-rar-compressed;base64,UEsDBAoAAAAAAKx4pVgvcG0lQAAAAEAAAAAMAAAAtePO0rXjztIudHh05ZOI5ZOI5ZOI77yM5piv5LiN5piv5oy65aW9546p55qEDQoNCuS9v+eUqOmTvuaOpeS8oOi+k+WOi+e8qeWMhVBLAQI/AAoAAAAAAKx4pVgvcG0lQAAAAEAAAAAMACQAAAAAAAAAIAAAAAAAAAC1487StePO0i50eHQKACAAAAAAAAEAGACtFN2Yup7aAVB935i6ntoBiknN7yme2gFQSwUGAAAAAAEAAQBeAAAAagAAAAAA" download="test.zip">点击下载</a>
|
点击下载
这样我们就可以直接使用这个md文件来展示下载链接了。