diff --git a/libraries/FS/src/FS.cpp b/libraries/FS/src/FS.cpp index f5e9a8ab2cc..80d0958a759 100644 --- a/libraries/FS/src/FS.cpp +++ b/libraries/FS/src/FS.cpp @@ -130,6 +130,15 @@ size_t File::size() const return _p->size(); } +bool File::setBufferSize(size_t size) +{ + if (!*this) { + return 0; + } + + return _p->setBufferSize(size); +} + void File::close() { if (_p) { diff --git a/libraries/FS/src/FS.h b/libraries/FS/src/FS.h index c3a1c51c5ec..64e630c4577 100644 --- a/libraries/FS/src/FS.h +++ b/libraries/FS/src/FS.h @@ -70,6 +70,7 @@ class File : public Stream } size_t position() const; size_t size() const; + bool setBufferSize(size_t size); void close(); operator bool() const; time_t getLastWrite(); diff --git a/libraries/FS/src/FSImpl.h b/libraries/FS/src/FSImpl.h index 4c5c9786840..bb20cd499ae 100644 --- a/libraries/FS/src/FSImpl.h +++ b/libraries/FS/src/FSImpl.h @@ -36,6 +36,7 @@ class FileImpl virtual bool seek(uint32_t pos, SeekMode mode) = 0; virtual size_t position() const = 0; virtual size_t size() const = 0; + virtual bool setBufferSize(size_t size) = 0; virtual void close() = 0; virtual time_t getLastWrite() = 0; virtual const char* path() const = 0; diff --git a/libraries/FS/src/vfs_api.cpp b/libraries/FS/src/vfs_api.cpp index 9e200a1500b..25a27c70bcf 100644 --- a/libraries/FS/src/vfs_api.cpp +++ b/libraries/FS/src/vfs_api.cpp @@ -13,11 +13,10 @@ // limitations under the License. #include "vfs_api.h" -#include using namespace fs; -#define READ_SIZE_SWITCH 128 //swithc to read func when read size > 128bytes +#define DEFAULT_FILE_BUFFER_SIZE 4096 FileImplPtr VFSImpl::open(const char* fpath, const char* mode, const bool create) { @@ -283,6 +282,10 @@ VFSFileImpl::VFSFileImpl(VFSImpl* fs, const char* fpath, const char* mode) if(!_f) { log_e("fopen(%s) failed", temp); } + if(_f && (_stat.st_blksize == 0)) + { + setvbuf(_f,NULL,_IOFBF,DEFAULT_FILE_BUFFER_SIZE); + } } else if(S_ISDIR(_stat.st_mode)) { _isDirectory = true; _d = opendir(temp); @@ -310,6 +313,10 @@ VFSFileImpl::VFSFileImpl(VFSImpl* fs, const char* fpath, const char* mode) if(!_f) { log_e("fopen(%s) failed", temp); } + if(_f && (_stat.st_blksize == 0)) + { + setvbuf(_f,NULL,_IOFBF,DEFAULT_FILE_BUFFER_SIZE); + } } } free(temp); @@ -377,28 +384,7 @@ size_t VFSFileImpl::read(uint8_t* buf, size_t size) return 0; } - //ERASE BYTEBUFFER and use read when size > READ_SIZE_SWITCH always - if(size > READ_SIZE_SWITCH) - { - //check some data in buffer exists –> clear buffer and move pointer to deleted data - size_t bytesinbuf = __fpending(_f); - if (bytesinbuf && (bytesinbuf != 128)) //buffer lenght is 128 bytes - { - fpurge(_f); - lseek(fileno(_f),(-128+bytesinbuf),SEEK_CUR); - } - - int res = ::read(fileno(_f), buf, size); - if (res < 0) { - // an error occurred - return 0; - } - return res; - } - else - { - return fread(buf, 1, size, _f); - } + return fread(buf, 1, size, _f); } void VFSFileImpl::flush() @@ -439,6 +425,19 @@ size_t VFSFileImpl::size() const return _stat.st_size; } +/* +* Change size of files internal buffer used for read / write operations. +* Need to be called right after opening file before any other operation! +*/ +bool VFSFileImpl::setBufferSize(size_t size) +{ + if(_isDirectory || !_f) { + return 0; + } + int res = setvbuf(_f,NULL,_IOFBF,size); + return res == 0; +} + const char* VFSFileImpl::path() const { return (const char*) _path; diff --git a/libraries/FS/src/vfs_api.h b/libraries/FS/src/vfs_api.h index f79852cdcfe..780c334aa5c 100644 --- a/libraries/FS/src/vfs_api.h +++ b/libraries/FS/src/vfs_api.h @@ -65,10 +65,11 @@ class VFSFileImpl : public FileImpl bool seek(uint32_t pos, SeekMode mode) override; size_t position() const override; size_t size() const override; + bool setBufferSize(size_t size); void close() override; const char* path() const override; const char* name() const override; - time_t getLastWrite() override; + time_t getLastWrite() override; boolean isDirectory(void) override; FileImplPtr openNextFile(const char* mode) override; void rewindDirectory(void) override;