瀑布流展现图片的新需求
我现已能够生成一些图片了,可是光看图片我能看出什么来?我需求展现出图片和图片的信息。这或许就要专门开发一下了。
我当时想,这个或许有点难,他是个前后端都有的程序。所以我就本能的想到,要不要找找有个库没有,先找个瀑布流展现图片的现成的库,在上面略微改改或许是比较简单的做法。害怕ChatGPT不可,我还去问了new bing,我想着,newbing的常识更新一点,所以我问:
指定一个path直接发动一个nodejs server,经过localhost拜访,以瀑布流方式展现path下一切图片的npm东西
结果他建议我运用node-static的库,所以我就追问了一些怎样用node-static库的办法去写代码,得到的代码或许由于常识过期,反正是不能用的,我就不贴在这儿了。
有点懊丧,这略微用点库你就给我撂挑子,你这果然也不可啊,一用库就犯错,你这果然担任不了杂乱开发。new bing不靠谱,我就又去问ChatGPT,一开始我问得有问题,我直接问:
用node-static库怎样完成:指定一个path直接发动一个nodejs server,经过localhost拜访,以瀑布流方式展现path下一切图片
结果显现的代码果然是不能用的,我心想对啊,new bing都没有新数据,你这个数据岂不是更糟糕?可是灵机一动之下,我也没退出,我就问
上面的代码不能运转,有没有别的办法?
然后我得到了下面的回答:
能够运用Node.js的http和fs模块来发动一个HTTP服务器,而且运用path模块来获取文件途径,以及运用mime模块来获取文件的MIME类型,然后经过HTML和CSS来创立一个简单的瀑布流布局。
以下是一个示例代码:
const http = require('http');
const fs = require('fs');
const path = require('path');
const mime = require('mime');
const PORT = 3000;
const PATH = './path'; // 设置图片目录的途径
http.createServer((req, res) => {
console.log(`Request for ${req.url}`);
// 假如请求的是根途径,回来图片列表页面
if (req.url === '/') {
res.writeHead(200, { 'Content-Type': 'text/html' });
// 读取图片目录下的一切文件
fs.readdir(PATH, (err, files) => {
if (err) {
console.error(err);
res.end('Error reading directory');
return;
}
// 运用HTML和CSS创立瀑布流布局
res.write(`
<html>
<head>
<title>Image Gallery</title>
<style>
.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-gap: 10px;
}
.item {
position: relative;
}
.item img {
width: 100%;
height: auto;
}
.item .caption {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
padding: 5px;
}
</style>
</head>
<body>
<div class="container">
`);
// 遍历一切文件,并在瀑布流布局中展现图片和文件名
files.forEach((file) => {
const filePath = path.join(PATH, file);
const mimeType = mime.getType(filePath);
if (mimeType && mimeType.startsWith('image/')) {
res.write(`
<div class="item">
<img src="https://juejin.im/post/7213267574770696247/${filePath}" alt="https://juejin.im/post/7213267574770696247/${file}">
<div class="caption">${file}</div>
</div>
`);
}
});
res.write(`
</div>
</body>
</html>
`);
res.end();
});
} else {
// 否则,回来请求的文件
const filePath = path.join(PATH, req.url);
const mimeType = mime.getType(filePath);
if (mimeType && mimeType.startsWith('image/')) {
// 假如请求的是图片文件,则回来图片数据
fs.readFile(filePath, (err, data) => {
if (err) {
console.error(err);
res.writeHead(404);
res.end('Not found');
return;
}
res.writeHead(200, { 'Content-Type': mimeType });
res.end(data);
});
} else {
// 否则,回来404过错
res.writeHead(404);
res.end('Not found');
}
}
}).listen(PORT);
console.log(`Server running at http://localhost:${PORT}`);
将上述代码保存为app.js文件,然后在终端中进入该文件地点的目录,并运转以下指令:
node app.js
运转该指令后,服务器将会在本地3000端口上发动。您能够在浏览器中输入http://localhost:3000/来检查图片列表,其中/表明根途径,这将会显现图片列表页面,瀑布流方式展现path下一切图片。假如您想直接拜访某张图片,能够经过输入其文件名来拜访,例如http://localhost:3000/example.jpg。请注意,在上述示例中,咱们假定一切图片文件的MIME类型都以image/开头,这通常是正确的,但假如您的图片文件类型不同,则或许需求修正相关代码。
咦?能够用原生写法啊,我立刻修正了自己的提问:
我需求用nodejs写一个后端服务,能够指定一个文件夹,按瀑布流显现下面一切的png图片。
要求:
- 能够经过传参指定任意根据index.js的相对文件夹及子文件夹
- 要并排显现png图片和png图片文件中的文本信息
- 页面要用BootStrap布局
- 我有一个模块:’./util/png_info/index’。 该模块导出的对象上有一个异步函数 readPng 能够读取 PNG 图像文件中的文本信息。不用完成,其签名为:
async function readPng(filePath) {
//....
}
- 指定index.js地点文件夹为静态文件夹
我得到了能够履行的代码:
const express = require('express');
const path = require('path');
const fs = require('fs');
const { readPng } = require('./util/png_info');
const app = express();
// 设置静态文件夹
app.use(express.static(path.join(__dirname)));
app.get('/images', async (req, res) => {
try {
const folderPath = req.query.folder;
const images = await getImages(folderPath);
const imagesHTML = await Promise.all(
images.map(async (image) => {
const info = await readPng(image.path);
return `
<div class="col-md-3">
<img src="https://juejin.im/post/7213267574770696247/${image.url}" class="img-thumbnail" alt="https://juejin.im/post/7213267574770696247/${image.name}">
<div class="text-muted">${info}</div>
</div>
`;
})
);
const html = `
<html>
<head>
<title>Image Gallery</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.2/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
${imagesHTML.join('')}
</div>
</div>
</body>
</html>
`;
res.send(html);
} catch (error) {
console.error(error);
res.status(500).send('Internal Server Error');
}
});
async function getImages(folderPath) {
const images = [];
const files = await fs.promises.readdir(folderPath, { withFileTypes: true });
for (const file of files) {
if (file.isDirectory()) {
const subfolderPath = path.join(folderPath, file.name);
const subfolderImages = await getImages(subfolderPath);
images.push(...subfolderImages);
} else if (file.name.endsWith('.png')) {
const url = path.join('/', path.relative(__dirname, folderPath), file.name).replace(/\\/g, '/');
images.push({ name: file.name, path: path.join(folderPath, file.name), url });
}
}
return images;
}
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
开悟时间
这一刻,我开悟了,对啊,要什么库啊!我需求从头反思我的作业习惯,曾经之所以要搞那么多的库为的是什么?现在这些库还有没有存在的必要要从头考虑一下。
比方这儿,我觉得写一个瀑布流很费事,所以我想到搞个库,这个是一个旧年代的思想定式。这是由于自己开发很花本钱,我自己写有或许会相关技能不熟有或许会写错,所以我的出产功率比较低。比方写一个例子里这样的东西,它涉及到十分多的常识点:nodejs的、css的、HTML的;还有许多集成点:前端后端你把它们连起来,或许会连错。太多的点要考虑了。这个每一个点上我或许我的常识储藏不可,或许我忘了,我还要从头去学习,从头去查找;又或许我在集成的时分,个人会犯太多的错,完了就要从头调试,都是本钱。所以我挑选了运用一个库。
可是运用一个库就没有本钱吗?查找是个本钱,学习是个本钱,然后呢你查的材料和现在的库有或许对不上,还会发生糟蹋,也是本钱。可是在曾经咱们就忍了,由于自己开发的本钱远远大于运用库的本钱。可是今日,关于ChatGPT来说,前面提到的自己开发的那些问题,它仍是问题吗?它不是问题啊。
然后我又想到前面的node-static库为什么不可?而你看在这个里面他也用了库,他用了express,用了fs,用了path。为什么后面这几个库就没有问题,前面那个node-static库就有问题?由于前面个库接口不安稳,ChatGPT学习到了旧版接口的运用办法,而那个库更新了。这么专用的一个库为什么要更新接口?还不是为了让人用的便利。由于或许会有人反应说你这个接口欠好理解,不容易理解。这个你能不能换一个接口?他这一换接口关于用新接口的人或许是舒畅的,可是关于像我这样只是想简单用一下的人就很郁闷了,由于材料都变了。很有或许会呈现我查了材料,照着写了代码,然后用不起来的状况。在软件开发的世界里面,这种事情不要太多。
关于 ChatGPT 来说,这种改变是好仍是坏?人在运用上那一点点细小的\心理上的爽感关于 ChatGPT 来说是没有任何优点的,反而是有害的。那么在今日这个年代,咱们为什么还要运用那些繁重的库?咱们是不是应该直接回归本源?就用最根底、最简单封装的库。这些都有一个特点。接口安稳。从诞生之初到现在没有太大改变。这个关于ChatGPT才是最友爱的。
推而广之
让咱们想象一下,比方Java企业开发范畴,是不是像是spring data这种东西。它的价值或许就不如SQL了,spring data这个东西一年不看都能有一大堆的改变,而sql这么多年了都没什么改变。这才是最好的。除非咱们能找到。SQL不能满意的场景。在那里封装一个简单的框架。比方说便是MyBatis。
所以在根据 ChatGPT 进行编程为条件,咱们进行技能栈选型时,依赖库接口的安稳性就变得格外重要了。不客气的说,在今日这个年代,接口的安稳性压倒一切。这就像在蒸汽机年代,铁轨的间距是不能随心随意的。只有安稳的铁轨间距。才会有高效的运送功率。同理,只有安稳的接口才干最大限度的发挥 ChatGPT 的才能,得到极高的开发功率。那些仅仅是由于帮助人少写几行代码而开发的。改变在今日这个年代,能不引进仍是不要引进。究竟你在上面包一层的本钱现已开始无限趋近于0了。你为什么还要让下面的接口迁就你呢?基层接口只要安稳的干好自己该干的事情,而且供给安稳的接口就够了。
这个改变关于今日十分多的企业中台都是一个重大利好。咱们知道许多企业中台这么多年都疲于奔命。沦为给前台的“大客户”打工。通常关于企业来说,前台分为几种?
一种是类似企业的“大客户”,便是企业里最赚钱的前台部门,那么咱们就要配很大的人力去服务好他,“大客户”自己呢,通常就固执一点,所以会把他们的需求直接扔给我。那咱们不得不改以适配“大客户”。
还有一些是小客户,可是由于都在企业里,你不能像在商场里相同说,小客户我就不管了,咱们是专做高端服务的。小客户你也要管,成年人全都要嘛。这中心的对立呢,就使得许多规划上本来现已说的很清楚的准则,根本落了地。
其实想想挺可笑的,过去那么多年,咱们都说,基层要安稳基层要安稳,结果基层总也安稳不了。为什么呢?不便是上层的新需求来了,非要让咱们基层的搞嘛。该咱们搞的,咱们搞,你们用着不便利也让咱们搞这是不是有点过分了,便利这个东西哪是有止境的呀?最便利的便是你们什么都不做,都让咱们做了,才最便利不是吗?这么搞它接口能安稳吗?
可是话又说回来了,曾经没有办法呀。中台有很强的开发力量,前台有吗?通常前台是没有的。而前台一句你欠好用,中台就政治不正确了,所以不得已咱们就要配许多的开发力量来处理这些非技能的所谓技能问题。究竟咱们都要为功率垂头嘛,前中后台端到端全局功率最高才是咱们追求的方向。你不能说我中台规划的好了,我功率高了,你全体功率上不去。你这个单点功率高又有什么用?
所以这便是个死局。曾经咱们都装作尽力在解,其实本质上都是十分原始的解法,解得一切人都痛苦。可是在今日咱们迎来了新的出产东西。让咱们看到了这个对立能够被消解的或许,由于安稳。不仅仅能够让中台的开发功率进步,也能够让前台开发功率进步。一个变化的接口,对前台也是不友爱的,究竟跟着 ChatGPT 这类大言语模型的推广,前台的开发才能被史诗级加强,咱们能够看到,微软在Power Platform上现已推出Copilot功用来实践这种模式了。
总结一下
开篇咱们引进了一个以瀑布流方式展现图片需求,一开始,咱们采用习惯的思路,测验运用一个库来处理这个问题。但马上就遇到了问题,这并不是ChatGPT擅长的事情,但是当我问 ChatGPT 有没有其他办法的时分,我得到了原生写法的处理方案。
这让咱们意识到在根据 ChatGPT 编程的布景下,从头审视库。过往的许多库都是会为了人们好用而不停地供给一些新的接口,这些接口让人们用着很舒畅,可是其实带来了学习本钱,以及学习材料的过期。许多人都不喜欢学习新技能,便是觉得乱,看起来也不是没有道理。
所以那些陈旧的可是仍然在用的库是更能发挥出 ChatGPT 的效能的。仍然在运用表明没有过期,仍然有价值,陈旧表明接口安稳,材料最全。所以咱们是不是要反思一下,发明那么多库有没有或许必定程度上走错了路。这让我想起三体里面,人类建了那么多的星际舰队,三体就搞了一个水滴,只用碰击这一个动作就把那些花里花哨的攻击办法给比下去了。这层彻悟导致我之后一段时间在技能群里看到有人问什么功用有没有现成的库的时分,不自觉的会在脑子里蹦出一个吐槽:“哼,原始人”。这心态很欠好,可是确实很恰当,也许跟着此类大言语模型AI的开展,咱们曾经的许多花里胡哨的做法真的看起来就很像传统武术里的许多招数,在热兵器面前不再具有普遍的价值。
那么推而广之,安稳的接口关于发挥ChatGPT的才能以进步开发功率至关重要。在技能栈选型时,安稳性应该成为优先考虑的要素。甚至于关于中台建造都有很大利好,在企业中台的建造中,前台和中台之间的对立导致中台的接口和功用都无法安稳。但是,跟着ChatGPT这类大言语模型的普及,前台的开发才能得到了极大的进步,让中台安稳成为或许,微软的Power Platform现已在摸索类似的模式了。
这一篇咱们讲了一个思路上改变,运用 ChatGPT 的过程中,经常会遇到这种思路改变的状况,每次改变都会觉得上一刻的自己是多么的愚笨。所以建议咱们赶快用起来,认知的改变或许会带来完全不同的风景。下一篇咱们讲讲另一个引起我思路改变的手法,这也是许多人用ChatGPT处理长内容时的一个思想盲区。