File
File 类层次结构
File 类以通用方式提供对文件系统的底层存储的访问。这充当文件系统与物理存储介质的任何技术限制之间的缓冲区。在存储上,每个文件都是由表示为字符串的文件名引用的数据块。通过为 File 类中的 open 函数提供文件名,您可以访问存储在磁盘上的 blob 数据。
File API 允许对存储的数据进行操作,而无需缓冲 RAM 中的数据。由于闪存比 RAM 便宜几个数量级,因此可以显着增加设备可以存储的数据量,而不会显着增加设备的成本。
注意: 要获取和设置文件的缓冲区,请跳转到读取和写入函数。在 File 类中,读写函数始终一次读取或写入整个文件。
文件的操作就像一卷无限长的磁带。每个 File 对象都会跟踪其在数据中的当前位置,并且在您读取或写入文件时此位置会更新。 当数据写入文件时,文件会增长,除非底层存储空间不足。如果基础文件系统支持,您可以使用 seek
和 rewind
功能显式移动文件位置。
在文件上组合 read
,write
和 seek
允许对存储在外部存储器上的数据进行流式传输和随机访问,而无需缓冲设备 RAM 上的文件内容。
File 类参考
公共成员函数 | |
File () | |
File (FileSystem *fs, const char *path, int flags=O_RDONLY) | |
virtual | ~File () |
virtual int | open (FileSystem *fs, const char *path, int flags=O_RDONLY) |
virtual int | close () |
virtual ssize_t | read (void *buffer, size_t size) |
virtual ssize_t | write (const void *buffer, size_t size) |
virtual int | sync () |
virtual int | isatty () |
virtual off_t | seek (off_t offset, int whence=SEEK_SET) |
virtual off_t | tell () |
virtual void | rewind () |
virtual off_t | size () |
公共成员函数继承自 mbed::FileHandle | |
virtual off_t | lseek (off_t offset, int whence) |
virtual int | fsync () |
virtual off_t | flen () |
virtual int | set_blocking (bool blocking) |
virtual bool | is_blocking () const |
virtual short | poll (short events) const |
bool | writable () const |
bool | readable () const |
virtual void | sigio (Callback< void()> func) |
文件系统示例
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed.h"
#include <stdio.h>
#include <errno.h>
// Block devices
#include "SPIFBlockDevice.h"
#include "DataFlashBlockDevice.h"
#include "SDBlockDevice.h"
#include "HeapBlockDevice.h"
// File systems
#include "LittleFileSystem.h"
#include "FATFileSystem.h"
// Physical block device, can be any device that supports the BlockDevice API
SPIFBlockDevice bd(
MBED_CONF_SPIF_DRIVER_SPI_MOSI,
MBED_CONF_SPIF_DRIVER_SPI_MISO,
MBED_CONF_SPIF_DRIVER_SPI_CLK,
MBED_CONF_SPIF_DRIVER_SPI_CS);
// File system declaration
LittleFileSystem fs("fs");
// Set up the button to trigger an erase
InterruptIn irq(BUTTON1);
void erase() {
printf("Initializing the block device... ");
fflush(stdout);
int err = bd.init();
printf("%s\n", (err ? "Fail :(" : "OK"));
if (err) {
error("error: %s (%d)\n", strerror(-err), err);
}
printf("Erasing the block device... ");
fflush(stdout);
err = bd.erase(0, bd.size());
printf("%s\n", (err ? "Fail :(" : "OK"));
if (err) {
error("error: %s (%d)\n", strerror(-err), err);
}
printf("Deinitializing the block device... ");
fflush(stdout);
err = bd.deinit();
printf("%s\n", (err ? "Fail :(" : "OK"));
if (err) {
error("error: %s (%d)\n", strerror(-err), err);
}
}
// Entry point for the example
int main() {
printf("--- Mbed OS filesystem example ---\n");
// Setup the erase event on button press, use the event queue
// to avoid running in interrupt context
irq.fall(mbed_event_queue()->event(erase));
// Try to mount the filesystem
printf("Mounting the filesystem... ");
fflush(stdout);
int err = fs.mount(&bd);
printf("%s\n", (err ? "Fail :(" : "OK"));
if (err) {
// Reformat if we can't mount the filesystem
// this should only happen on the first boot
printf("No filesystem found, formatting... ");
fflush(stdout);
err = fs.reformat(&bd);
printf("%s\n", (err ? "Fail :(" : "OK"));
if (err) {
error("error: %s (%d)\n", strerror(-err), err);
}
}
// Open the numbers file
printf("Opening \"/fs/numbers.txt\"... ");
fflush(stdout);
FILE *f = fopen("/fs/numbers.txt", "r+");
printf("%s\n", (!f ? "Fail :(" : "OK"));
if (!f) {
// Create the numbers file if it doesn't exist
printf("No file found, creating a new file... ");
fflush(stdout);
f = fopen("/fs/numbers.txt", "w+");
printf("%s\n", (!f ? "Fail :(" : "OK"));
if (!f) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
for (int i = 0; i < 10; i++) {
printf("\rWriting numbers (%d/%d)... ", i, 10);
fflush(stdout);
err = fprintf(f, " %d\n", i);
if (err < 0) {
printf("Fail :(\n");
error("error: %s (%d)\n", strerror(errno), -errno);
}
}
printf("\rWriting numbers (%d/%d)... OK\n", 10, 10);
printf("Seeking file... ");
fflush(stdout);
err = fseek(f, 0, SEEK_SET);
printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
if (err < 0) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
}
// Go through and increment the numbers
for (int i = 0; i < 10; i++) {
printf("\rIncrementing numbers (%d/%d)... ", i, 10);
fflush(stdout);
// Get current stream position
long pos = ftell(f);
// Parse out the number and increment
int32_t number;
fscanf(f, "%d", &number);
number += 1;
// Seek to beginning of number
fseek(f, pos, SEEK_SET);
// Store number
fprintf(f, " %d\n", number);
// Flush between write and read on same file
fflush(f);
}
printf("\rIncrementing numbers (%d/%d)... OK\n", 10, 10);
// Close the file which also flushes any cached writes
printf("Closing \"/fs/numbers.txt\"... ");
fflush(stdout);
err = fclose(f);
printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
if (err < 0) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
// Display the root directory
printf("Opening the root directory... ");
fflush(stdout);
DIR *d = opendir("/fs/");
printf("%s\n", (!d ? "Fail :(" : "OK"));
if (!d) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
printf("root directory:\n");
while (true) {
struct dirent *e = readdir(d);
if (!e) {
break;
}
printf(" %s\n", e->d_name);
}
printf("Closing the root directory... ");
fflush(stdout);
err = closedir(d);
printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
if (err < 0) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
// Display the numbers file
printf("Opening \"/fs/numbers.txt\"... ");
fflush(stdout);
f = fopen("/fs/numbers.txt", "r");
printf("%s\n", (!f ? "Fail :(" : "OK"));
if (!f) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
printf("numbers:\n");
while (!feof(f)) {
int c = fgetc(f);
printf("%c", c);
}
printf("\rClosing \"/fs/numbers.txt\"... ");
fflush(stdout);
err = fclose(f);
printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
if (err < 0) {
error("error: %s (%d)\n", strerror(errno), -errno);
}
// Tidy up
printf("Unmounting... ");
fflush(stdout);
err = fs.unmount();
printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
if (err < 0) {
error("error: %s (%d)\n", strerror(-err), err);
}
printf("Mbed OS filesystem example done!\n");
}