feat(fs/read): read part of a file in an existing Buffer (#3036)

Easier to use and probably more efficient than `createReadStream` for this specific usage.
This commit is contained in:
Julien Fontanet
2018-06-07 17:19:33 +02:00
committed by GitHub
parent 10baecefb9
commit b207cbdd77
4 changed files with 45 additions and 18 deletions

View File

@@ -92,6 +92,22 @@ export default class RemoteHandlerAbstract {
await promise
}
async read (
file: File,
buffer: Buffer,
position?: number
): Promise<{| bytesRead: number, buffer: Buffer |}> {
return this._read(file, buffer, position)
}
_read (
file: File,
buffer: Buffer,
position?: number
): Promise<{| bytesRead: number, buffer: Buffer |}> {
throw new Error('Not implemented')
}
async readFile (file: string, options?: Object): Promise<Buffer> {
return this._readFile(file, options)
}

View File

@@ -50,6 +50,24 @@ export default class LocalHandler extends RemoteHandlerAbstract {
await fs.writeFile(path, data, options)
}
async _read (file, buffer, position) {
const needsClose = typeof file === 'string'
file = needsClose ? await fs.open(this._getFilePath(file), 'r') : file.fd
try {
return await fs.read(
file,
buffer,
0,
buffer.length,
position === undefined ? null : position
)
} finally {
if (needsClose) {
await fs.close(file)
}
}
}
async _readFile (file, options) {
return fs.readFile(this._getFilePath(file), options)
}

View File

@@ -24,7 +24,6 @@
"async-iterator-to-stream": "^1.0.2",
"from2": "^2.3.0",
"fs-extra": "^6.0.1",
"get-stream": "^3.0.0",
"limit-concurrency-decorator": "^0.4.0",
"promise-toolbox": "^0.9.5",
"struct-fu": "^1.2.0",
@@ -41,6 +40,7 @@
"cross-env": "^5.1.3",
"execa": "^0.10.0",
"fs-promise": "^2.0.0",
"get-stream": "^3.0.0",
"index-modules": "^0.3.0",
"rimraf": "^2.6.2",
"tmp": "^0.0.33"

View File

@@ -1,5 +1,4 @@
import assert from 'assert'
import getStream from 'get-stream'
import { fromEvent } from 'promise-toolbox'
import constantStream from './_constant-stream'
@@ -93,20 +92,14 @@ export default class Vhd {
// Read functions.
// =================================================================
_readStream (start, n) {
return this._handler.createReadStream(this._path, {
start,
end: start + n - 1, // end is inclusive
})
}
_read (start, n) {
return this._readStream(start, n)
.then(getStream.buffer)
.then(buf => {
assert.equal(buf.length, n)
return buf
})
async _read (start, n) {
const { bytesRead, buffer } = await this._handler.read(
this._path,
Buffer.alloc(n),
start
)
assert.equal(bytesRead, n)
return buffer
}
containsBlock (id) {
@@ -336,11 +329,11 @@ export default class Vhd {
`freeFirstBlockSpace: move first block ${firstSector} -> ${newFirstSector}`
)
// copy the first block at the end
const stream = await this._readStream(
const block = await this._read(
sectorsToBytes(firstSector),
fullBlockSize
)
await this._write(stream, sectorsToBytes(newFirstSector))
await this._write(block, sectorsToBytes(newFirstSector))
await this._setBatEntry(first, newFirstSector)
await this.writeFooter(true)
spaceNeededBytes -= this.fullBlockSize