How to save filestream as a file in a folder in node
Solution 1
This is the code that worked for me. I'm using Apollo Server and Graphql and 'singleUpload' is the resolver I created for uploading an image.
const path = require("path");
const { createWriteStream } = require("fs");
Both these imports are already included in the node package so you don't need to install them separately.
singleUpload: async (_, { file }) => {
const { createReadStream, filename, mimetype, encoding } = await file;
await new Promise((res) =>
createReadStream()
.pipe(
createWriteStream(
path.join(__dirname, "../../uploads/images", filename)
)
)
.on("close", res)
);
return true;
}
}
};
The 'file' is the image file I forwarded from <input type="file"/>
. The apollo-upload-client in the front-end automatically stores the stream in the 'createReadStream()' that I can destructure form the incoming file promise. I then pipe that stream using 'createWriteStream' and store it in the path I specify on my server. The path within the createWriteStream function is relative to your current directory and the server will look for this folder during runtime, so make sure it exists.
One last thing, if you're serving these images to the front-end directly from the server, make sure to include the line below in your main index.js server file.
app.use("/images", express.static(path.join(__dirname, "./uploads/images")));
Solution 2
I was helped by the apollo-upload-server
author regarding this issue. Just in case someone would encounter this issue, here is how to save the stream to a file:
const storeFS = ({ stream, filename }) => {
const uploadDir = './uploads';
const path = `${uploadDir}/${filename}`;
return new Promise((resolve, reject) =>
stream
.on('error', error => {
if (stream.truncated)
// delete the truncated file
fs.unlinkSync(path);
reject(error);
})
.pipe(fs.createWriteStream(path))
.on('error', error => reject(error))
.on('finish', () => resolve({ path }))
);
}
Source: https://github.com/jaydenseric/apollo-upload-examples/blob/master/api/resolvers.mjs#L18
Related videos on Youtube
Woppi
Updated on June 04, 2022Comments
-
Woppi almost 2 years
When I upload a file, the server is returning a
stream
,filename
,mimetype
,encoding
. I can't figure out how to save the stream as a file in my server. I triedfs.createReadStream
, I just can't figure out the next steps for it like how do I put it in./uploads
folder?{ stream: FileStream { _readableState: [Object], readable: true, domain: null, _events: [Object], _eventsCount: 2, _maxListeners: undefined, truncated: false, _read: [Function] }, filename: 'test-sample.xlsx', mimetype: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', encoding: '7bit' } }
-
David R almost 6 yearsHi Woopi, Check out this thread => stackoverflow.com/questions/34820702/… and see if it is helpful
-
-
Alexander Kachkaev over 5 yearsUsing
stream
producesDeprecationWarning: File upload property ‘stream’ is deprecated. Use ‘createReadStream()’ instead.
The solution is to use{ createReadStream, filename }
andcreateReadStream().on(...)
. Source: github.com/apollographql/apollo-server/issues/… -
kubido over 5 yearsHi, I try the code above.. and my file is always return this error message:
Request disconnected during file upload stream parsing.