初识MATLAB之文件读取 - 一次性炮灰

初识MATLAB之文件读取

初识MATLAB之文件读取

  MATLAB的每一个脚本文件,几乎都涉及到文件的读写操作,我以几个案例来分析MATLAB的文件读取的基本操作。

1. 打开与关闭文件

  打开文件的函数为fopen,关闭文件的函数为fclose。这里将MATLAB中help帮助的内容拿出来介绍具体。

  FID = fopen(FILENAME,PERMISSION) 打开文件FILENAME, 由PERMISSION指定的模式:

  \'r\'    打开文件进行阅读

  \'w\'   打开文件写; 丢弃现有内容

  \'a\'   打开或创建文件以供写作; 将数据附加到文件末尾

  \'r+\'   打开(不创建)文件进行读写

  \'w+\'   打开或创建文件进行阅读和写作; 丢弃现有内容

  \'a+\'   打开或创建文件进行阅读和写作; 将数据附加到文件末尾

  \'W\'   打开文件进行写入而不自动刷新

  \'A\'    打开文件,无需自动刷新即可追加  

  仅当文件时,FILENAME可以是MATLABPATH相对部分路径名打开阅读。

  您可以以二进制模式(默认)或文本模式打开文件。在二进制模式下,没有任何字符被挑出来进行特殊处理。在PC上的文本模式中,前面有回车符在输入中删除换行符并在换行符之前添加输出中的字符。 要以文本模式打开文件,请将“t”附加到权限字符串,例如\'rt\'和\'w + t\'。 (在Unix上,文本和二进制模式是相同的,所以这没有效果。 在PC系统上 这很关键。)

  status = fclose(FID)  丢失与文件标识符FID关联的文件,这是从早先调用FOPEN获得的整数值。 fclose如果成功则返回0,否则返回-1。 如果FID不代表打开文件,或者等于0(标准输入),1(标准输出),或2(标准错误),fclose引发错误。

  以下为一个打开与关闭文件的案例:

>> filename=\'input.txt\';
permission=\'r\';
fid=fopen(filename,permission),
status=fclose(fid)

  案例分析:文件名input.txt ,打开方式只读,文件标识为4,status 为0,关闭正常。

fid =

     4


status =

     0

2. fwrite和fread函数

  使用fwrite和fread函数来对二进制文件进行读写,这里有三个案例,分别为写操作案例,读操作案例和不能同时读写案例。

2.1 fwrite函数

  MATLAB中help帮助中对fwrite函数是这样介绍的:

  COUNT = fwrite(FID,A,PRECISION)  写出矩阵A的元素到指定的文件,将MATLAB值转换为指定的值精确。

  PRECISION控制结果的形式和大小。 查看列表FREAD允许的精度。 如果未指定PRECISION,MATLAB使用默认值,即\'uint8\'。 如果是\'bitN\'或\'ubitN\'用于PRECISION,然后用于任何超出范围的值A.被写为一个值,所有位都打开。 如果精度是\'char\'或\'char * 1\',MATLAB使用编码写字符与文件关联的方案。 有关更多信息,请参见FOPEN。

filename=\'input2.bin\';
permission=\'r+\';
fid=fopen(filename,permission);
a=magic(5);
precision=\'int32\';
count=fwrite(fid,a,precision),
status=fclose(fid)

  案例分析:文件名input2.bin,打开方式读写,status 为0,关闭正常。写入的矩阵为特殊矩阵magic(5),count 为25,表示写入了25个元素,是正确的。

count =

    25


status =

     0

2.1 fread函数

  MATLAB中help帮助中对fread函数是这样介绍的:

   A = fread(FID,SIZE,PRECISION)   根据文件来阅读文件字符串PRECISION指定的数据格式。该PRECISION输入通常包含一个数据类型说明符\'int\'或\'float\',后跟一个给出大小的整数位。 使用此语法时,SIZE参数是可选的。   

  以下任何字符串,MATLAB版本或可以使用它们的C或Fortran等价物。 如果没有指定,默认精度为\'uint8\'。

>> filename=\'input2.bin\';
permission=\'r+\';
fid=fopen(filename,permission);
precision=\'int32\';
data=reshape(fread(fid,count,precision),5,5)
status=fclose(fid)

  案例分析:文件名input2.bin,打开方式读写,status 为0,关闭正常。由2.1的案例可知写入的矩阵为特殊矩阵magic(5),使用fread函数读出的矩阵为data,如下所示。

data =

    17    24     1     8    15
    23     5     7    14    16
     4     6    13    20    22
    10    12    19    21     3
    11    18    25     2     9


status =

     0

2.3 不能同时读写案例

  当分别实现了读写文件后,我想可不可以在同一次打开的文件中,先进行写操作,再进行读操作。案例(至少这个)证实我不能这样干。但可以进行完写吃操作后关闭文件在打开再进行读文件操作。详见4.中的案例。(如果可以这样做是我没法实现,请评论留言,谢谢)

>> filename=\'input2.bin\';
permission=\'r+\';
fid=fopen(filename,permission);
a=magic(5);
precision=\'int32\';
count=fwrite(fid,a,precision);
data=reshape(fread(fid,count,precision),5,5)
status=fclose(fid)

  案例分析:以下为报错结果,我没法解决。

Error using reshape
To RESHAPE the number of elements must not change.

3. fprintf和fscanf函数

  使用fprintf和fscanf函数来对文本文件进行读写,这里有两个案例,分别为写操作案例和读操作案例。

3.1 fprintf函数

  MATLAB中help帮助中对fprintf函数是这样介绍的:

  fprintf(FID, FORMAT, A, ...)   将FORMAT应用于所有元素数组A和列顺序中的任何其他数组参数,并写入数据到文本文件。 FID是整数文件标识符。 获得来自FOPEN的FID,或将其设置为1(标准输出,屏幕)或2(标准错误)。 fprintf使用中指定的编码方案打电话给FOPEN。

>> filename=\'input2.txt\';
permission=\'r+\';
fid=fopen(filename,permission);
a=magic(5);
format=\'%d %d %d %d %d\n\';
count=fprintf(fid,format,a);
status=fclose(fid),
type input2.txt

  案例分析:文件名input2.txt,打开方式读写,status 为0,关闭正常。写入的矩阵为特殊矩阵magic(5),type input2.txt,表示显示 input2.txt文件中的内容,如下所示是正确的。且写入文件中的格式为\'%d %d %d %d %d\n\',代表每个元素以‘ ’隔开,且每个5就换行。

status =

     0


17 23 4 10 11
24 5 6 12 18
1 7 13 19 25
8 14 20 21 2
15 16 22 3 9

3.2 fscanf函数

  MATLAB中help帮助中对fscanf函数是这样介绍的:

  fscanf(FID,FORMAT,SIZEA)   从文本文件中读取和转换数据按列顺序进入数组A. FID是从中获取的文件标识符FOPEN。 COUNT是一个可选的输出参数,返回数字元素成功阅读 。  

  FORMAT是包含普通字符和/或转换的字符串规范,包括%字符,可选星号赋值抑制,可选的宽度字段和转换字符(例如d,i,o,u,x,e,f,g,s或c)。

  将SIZEA元素放入A.SIZEA的有效表格是:

inf读取到文件末尾。 (默认)
N最多将N个元素读入列向量。
[M,N]读取至多填充M-by-N矩阵的M * N个元素

按列顺序。 N可以是inf,但M不能。

>> filename=\'input2.txt\';
permission=\'r+\';
fid=fopen(filename,permission);
a=magic(5);
format=\'%d\';
count=fscanf(fid,format,[5,inf]),
status=fclose(fid),
type input2.txt

  案例分析:文件名input2.txt,打开方式读写,status 为0,关闭正常。由3.1的案例可知写入的矩阵为特殊矩阵magic(5),使用函数fscanf读出的矩阵为count,如下所示。且与type input2.txt所给出的矩阵对比,说明使用正确。

count =

    17    24     1     8    15
    23     5     7    14    16
     4     6    13    20    22
    10    12    19    21     3
    11    18    25     2     9


status =

     0


17 23 4 10 11
24 5 6 12 18
1 7 13 19 25
8 14 20 21 2
15 16 22 3 9

4. 文件读写位置控制

  我们可以自主控制文件的读写的位置。主要有四个函数,feof函数,frewind函数,fseek函数,ftell函数。以下案例将打开与关闭文件,读与写文本文件的操作都复习了一遍。且简单介绍feof函数,frewind函数,fseek函数,ftell函数的内容:

  ST = feof(FID) 如果文件结束指示符,则返回1已设置文件标识符FID的文件,否则为0。当对文件执行读取操作时,将设置文件结束指示符与FID相关联的尝试读取超过文件末尾的内容。

  frewind(FID)  将文件位置指示器设置为开头与文件标识符FID关联的文件。

  STATUS = fseek(FID, OFFSET, ORIGIN)  重新定位文件位置与给定FID关联的文件中的指示符。 fseek设置了位置指示符指向相对于指定OFFSET的字节起源。

  OFFSET值解释如下:

> = 0在ORIGIN之后移动位置指示符OFFSET字节。

<0在ORIGIN之前移动位置指示器OFFSET字节。

  ORIGIN值解释如下:

\'bof\'或-1文件开头

\'cof\'或0文件中的当前位置

\'eof\'或1文件结尾

  POSITION = ftell(FID)  返回文件位置的位置指定文件中的指示符。 位置以字节表示从文件的开头。 如果返回-1,则表示查询不成功。 使用FERROR来确定性质的错误。

 1 >> filename=\'input2.txt\';
 2 permission=\'r+\';
 3 fid1=fopen(filename,permission);
 4 a=magic(5);
 5 format=\'%d %d %d %d %d\n\';
 6 count=fprintf(fid1,format,a);
 7 status=fclose(fid1),
 8 fid2=fopen(filename,permission);
 9 a=magic(5);
10 format=\'%d\';
11 count=fscanf(fid2,format,[5,inf]),
12 eof=feof(fid2),
13 frewind(fid2),
14 status=fseek(fid2,3,0),
15 position=ftell(fid2),
16 status=fclose(fid2),

  案例分析:eof为0,代表文件的末尾指示值未被设定,第20行的status 为0,代表,设定指针位置操作成功。position 为3,代表指针距离文件起始位置的距离为3字节。第30行和第1行的status代表文件关闭正常

 1 status =
 2 
 3      0
 4 
 5 
 6 count =
 7 
 8     17    24     1     8    15
 9     23     5     7    14    16
10      4     6    13    20    22
11     10    12    19    21     3
12     11    18    25     2     9
13 
14 
15 eof =
16 
17      0
18 
19 
20 status =
21 
22      0
23 
24 
25 position =
26 
27      3
28 
29 
30 status =
31 
32      0

  总结:内容的总结不想写了,特别提及一点,这次我真正学会了代码粘贴的正确姿势。最后如果你对内容有所疑问可评论留言。谢谢阅读。