Nodejs版本 v0.10.15,用createReadStream始终没法下载文件,求Nodejs解决方案

Nodejs版本 v0.10.15,用createReadStream始终没法下载文件,求Nodejs解决方案

尝试过各种办法,百度都翻了好几篇了。,还是没解决 代码如下。

filePath = “D:/web/4.jpg”; function readFile(filePath,response) { filePath = path.join(filePath);

var ContentType;
if(filePath.lastIndexOf(".") == -1)
	throw new Error("Directory is not support download!");
var fileType = filePath.substring(filePath.lastIndexOf(".")+1);//文件类型
ContentType = config.MIME_TYPES[fileType]||"application/octet-stream";
fs.exists(filePath,function(exists){
	if (exists) {
		var rOption = {
			flags : 'r',
			encoding : null,
			fd: null,
			mode : 0666,
			autoClose: true
		}
		if(config.DEBUG)
			console.log("["+core.time()+"] GET files:"+filePath);
		var ReadStream = fs.createReadStream(filePath,rOption);
		ReadStream.on('data',function(data){
			response.write(data);
		});
  //ReadStream.on("data",function(data)
  //{
    //response.write(data);
  //});
		ReadStream.on("error", function() {
			if(config.DEBUG)
				console.log("["+core.time()+"] read files:"+filePath+" has an error!");
			response.writeHead(404,{"Content-Type": "text/plain"}); 
			response.end();
		});
		response.writeHead(200, {"Content-Type": ContentType});
		ReadStream.pipe(response);
		//response.write(filePath);
		ReadStream.on("end", function() {
			//数据发送完毕
			if(config.DEBUG)
				console.log("["+core.time()+"] read files:"+filePath+" success!");
			response.end();
		});
	}else{
		if(config.DEBUG)
			console.log("["+core.time()+"] files:"+filePath+" not exist!");
		response.writeHead(404,{"Content-Type": "text/plain"});
		response.end();
	}
});

}

假如按上面那种方式,浏览器一片空白。没有任何图片下载或显示 假如将ReadStream.pipe(response);注释掉 将//ReadStream.on(“data”,function(data) //{ //response.write(data); //}); 解除注释,可以触发end方法。 我确定文件存在的。 因为console.log("["+core.time()+"] GET files:"+filePath);这句可以在cmd中显示出来 response.write(data);始终返回的null 是不是这个版本的api有问题阿。为什么一直都不行呢?还是说有其他的问题?


4 回复

根据你的描述,你正在使用 Node.js 版本 v0.10.15,并且遇到了 fs.createReadStream 在下载文件时的一些问题。以下是可能的解决方案及优化后的代码。

首先,确保你已经导入了必要的模块:

const fs = require('fs');
const path = require('path');

然后,你可以优化你的代码如下:

const filePath = "D:/web/4.jpg";

function readFile(filePath, response) {
    filePath = path.resolve(filePath);

    var contentType;
    if (filePath.lastIndexOf(".") === -1) {
        throw new Error("Directory is not supported for download!");
    }
    
    const fileType = filePath.substring(filePath.lastIndexOf(".") + 1);
    contentType = config.MIME_TYPES[fileType] || "application/octet-stream";

    fs.exists(filePath, function (exists) {
        if (!exists) {
            console.log("[" + core.time() + "] File:" + filePath + " does not exist!");
            response.writeHead(404, { "Content-Type": "text/plain" });
            response.end();
            return;
        }

        if (config.DEBUG) {
            console.log("[" + core.time() + "] GET file:" + filePath);
        }

        const readStream = fs.createReadStream(filePath);

        readStream.on('error', function () {
            if (config.DEBUG) {
                console.log("[" + core.time() + "] Reading file:" + filePath + " encountered an error!");
            }
            response.writeHead(404, { "Content-Type": "text/plain" });
            response.end();
        });

        response.writeHead(200, { "Content-Type": contentType });
        readStream.pipe(response);

        readStream.on('end', function () {
            if (config.DEBUG) {
                console.log("[" + core.time() + "] Reading file:" + filePath + " completed successfully!");
            }
            response.end();
        });
    });
}

解释:

  1. 错误处理:当文件不存在时,直接返回 404 状态码。
  2. 使用 path.resolve():确保路径解析正确。
  3. 删除不必要的 data 事件监听器:直接使用 pipe() 方法来传输数据,这比手动监听 data 事件更高效。
  4. 简化逻辑:减少重复的代码,使逻辑更加清晰。

这样修改后,你应该能够正常下载文件。如果你仍然遇到问题,请检查 config.MIME_TYPES 是否正确配置以及 core.time() 函数是否正确实现。


  res.setHeader('Content-Disposition', 'attachment; filename="h5conf.csv"');
  res.setHeader('Content-Type', 'text/csv; charset=utf-8');
  res.end(result);

干净!

根据你的描述,问题可能与Node.js v0.10.15版本中的某些API行为有关。这个版本的Node.js已经非常老旧,很多API的行为和现代版本有所不同。以下是一些可能的改进点和建议:

改进代码

你可以尝试简化代码,并确保正确处理流。以下是修改后的代码示例:

const fs = require('fs');
const path = require('path');

function readFile(filePath, response) {
  const contentType = getContentType(filePath);

  if (!contentType) {
    response.writeHead(400, { "Content-Type": "text/plain" });
    response.end("Unsupported file type.");
    return;
  }

  const fileStream = fs.createReadStream(filePath);
  
  fileStream.on('open', () => {
    response.writeHead(200, { "Content-Type": contentType });
    fileStream.pipe(response);
  });

  fileStream.on('error', (err) => {
    response.writeHead(404, { "Content-Type": "text/plain" });
    response.end(`File not found: ${filePath}`);
  });

  fileStream.on('end', () => {
    response.end();
  });
}

function getContentType(filePath) {
  const ext = path.extname(filePath).toLowerCase();
  const MIME_TYPES = {
    '.jpg': 'image/jpeg',
    '.jpeg': 'image/jpeg',
    '.png': 'image/png',
    '.gif': 'image/gif'
  };
  return MIME_TYPES[ext] || 'application/octet-stream';
}

// 示例调用
readFile('D:/web/4.jpg', res);

解释

  1. 简化流处理:直接使用ReadStreampipe方法来处理响应,这样可以减少手动处理data事件的可能性。
  2. 错误处理:增加了对fileStream的错误处理,确保在发生错误时能够正确地返回状态码和消息。
  3. 获取MIME类型:通过一个简单的函数来确定文件的MIME类型,而不是硬编码。

版本兼容性

尽管上述代码应该能在v0.10.15版本上工作,但强烈建议升级到最新的Node.js版本(例如v14+),因为旧版本可能存在已知的问题和不支持的功能。

回到顶部