【发布时间】:2021-01-10 18:48:15
【问题描述】:
我正在尝试进行数据迁移。我们曾经将图像存储为 MySQL DB 中的 mediumblob 数据,我想读取此图像(blob 数据)并上传到谷歌云存储桶。上传成功,但云存储中的图像已损坏。
上传文件的代码
const id: string = uuidv4();
const buffer: Buffer = image.ImageBin; //image.ImageBin contains blob data from DB
let file = {
originalname: imageId + ".JPG",
buffer,
};
return await upload(file, id);
上传功能
public async upload(file, imageId): Promise<string> {
try {
const bucket = this.storage.bucket(process.env.IMAGE_BUCKET);
return new Promise((resolve, reject) => {
let { originalname, buffer } = file;
originalname = imageId + ":" + originalname;
originalname = originalname.replace(/ /g, "_");
const blob = bucket.file(originalname);
const blobStream = blob.createWriteStream({
resumable: false,
});
blobStream
.on("finish", () => {
const publicUrl = format(
`https://storage.googleapis.com/${bucket.name}/${blob.name}`
);
resolve(originalname);
})
.on("error", (error) => {
reject(error);
})
.end(buffer);
});
} catch (error) {
this.logger.log(`error uploading file error:${error}`);
}
}
用于从 mysql 获取图像的早期 Java 代码,此代码运行良好。
public Response getImage(Integer imageid, HttpServletResponse resp)
{
Response response = null;
UserPhotoUpload UserPhotoUpload = new UserPhotoUpload();
Blob imageBlob;
OutputStream out = null;
try
{
// get the image to upload
UserPhotoUpload = userPhotoUploadDAO.getImage(imageid);
if (UserPhotoUpload != null)
{
imageBlob = UserPhotoUpload.getImageBin();
if (imageBlob != null)
{
// get the output stream
out = resp.getOutputStream();
// add header info
resp.setHeader("Content-Disposition", "inline;filename=test.JPG");
resp.setContentType("Content-type: image/JPG");
// copy the image to the output stream
IOUtils.copy(imageBlob.getBinaryStream(), out);
out.flush();
out.close();
}
else
throw new ScottsAppException(CommonConstants.STATUS_MSG_ERROR_IMAGE_NOT_EXISTS);
}
else
throw new ScottsAppException(CommonConstants.STATUS_MSG_ERROR_IMAGE_NOT_EXISTS);
}
catch (ScottsAppException e)
{
response = new Response();
CommonUtil.responseErrorUpdate(response, e.getMessage(), CommonConstants.STATUS_CODE_APPLICATION_FAILURE);
}
catch (IOException e)
{
response = new Response();
log.error("Error", e);
CommonUtil.responseErrorUpdate(response, CommonConstants.STATUS_MSG_MISC_APPLICATION_FAILURE, CommonConstants.STATUS_CODE_APPLICATION_FAILURE);
}
catch (SQLException e)
{
response = new Response();
log.error("Error", e);
CommonUtil.responseErrorUpdate(response, CommonConstants.STATUS_MSG_MISC_APPLICATION_FAILURE, CommonConstants.STATUS_CODE_APPLICATION_FAILURE);
}
catch (Exception e)
{
response = new Response();
log.error("Error", e);
CommonUtil.responseErrorUpdate(response, CommonConstants.STATUS_MSG_MISC_APPLICATION_FAILURE, CommonConstants.STATUS_CODE_APPLICATION_FAILURE);
}
finally
{
try
{
out.flush();
}
catch (Exception e)
{
}
try
{
out.close();
}
catch (Exception e)
{
}
}
// return
return response;
}
如果有人不想查看 blob 数据 https://justpaste.it/862mk
【问题讨论】:
-
我对你的问题有点困惑,你提到你有一个早期版本的 Java 代码能够从数据库中获取图像,所以这意味着第一个代码块在哪里问题正在发生?上传Java功能之前是否有效?
-
@RafaelLemos 是的,java 代码工作正常,它能够发送表中的 blob 数据。 Nodejs 代码不工作,确定原因。
-
好的,但是你有一个非常小的 node.js 代码的 sn-p,这个值是从哪里来的
const buffer: Buffer = image.ImageBin;?我想我更大的问题是这里的执行顺序是什么?我的意思是,是按getImage() -> node.js code -> upload()顺序运行所有 3 个 sn-ps,还是试图用这个新的 node.js 函数替换“旧”java 函数?如果您有更多相关的 node.js 代码,也请分享。 -
image.ImageBin 是来自 mysql 数据库的 blob 数据,其中列名为 ImageBin。用于使用 API 将 blob 数据直接提供给 UI 的旧 java 代码。对于数据迁移,我需要创建一个图像并使用此 blob 数据上传到谷歌云存储。
-
我认为问题在于您没有将 blob 正确转换为节点代码中的缓冲区,请尝试为此替换该行:
const buffer = new Buffer( image.ImageBin, 'binary' );让我知道这是否有效。
标签: node.js google-cloud-storage blob