找回密码
 注册
关于网站域名变更的通知
查看: 331|回复: 1
打印 上一主题 下一主题

#技术风云榜#转一个网友分享的文档读取技巧教程

[复制链接]
  • TA的每日心情
    开心
    2019-11-29 15:41
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    跳转到指定楼层
    1#
    发表于 2020-11-24 15:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

    EDA365欢迎您登录!

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    转一个网友分享的文档读取技巧教程
    ; v' b% L6 N+ m5 ^  Q) F
      `) r) _# B: J# r" ^  A) ~
    由于大家在 I/O 存取上以 txt 文件为主,且读取比存储更麻烦(存储的话 fwrite, fprintf 基本够用),因此下面的讨论主要集中在“txt 文件的读取”上。除了标注了“转”之外,其余均转自技术论坛。- {+ C: G& z' B' I$ F7 w
    & T5 U3 N* H. N- H1 K8 {$ ?
    一. 基本知识:
    " U. O  ?2 w: \0 r: |1 p* U1 L--------------------------------------------------转----------------------------------------------------
    9 J4 R& C7 R8 Z$ @6 m4 k; c1. 二进制文件与文本文件的区别:
    5 s! D5 V$ Z+ A; c2 n将文件看作是由一个一个字节(byte) 组成的, 那么文本文件中的每个字节的最高位都是0,也就是说文本文件使用了一个字节中的七位来表示所有的信息,而二进制文件则是将字节中的所有位都用上了。这就是两者的区别;接着,第二个问题就是文件按照文本方式或者二进制方式打开,两者会有什么不同呢?其实不管是二进制文件也好,还是文本文件也好,都是一连串的0和1,但是打开方式不同,对于这些0和1的处理也就不同。如果按照文本方式打开,在打开的时候会进行translate,将每个字节转换成ASCII码,而以按照二进制方式打开的话,则不会进行任何的translate;最后就是文本文件和二进制文件在编辑的时候,使用的方式也是不同的。譬如,你在记事本中进行文本编辑的时候,你进行编辑的最小单位是字节(byte);而对二进制文件进行编辑的话,最小单位则是位(bit),当然我们都不会直接通过手工的方式对二进制文件进行编辑了。
    $ J8 n0 Z1 T0 a! {* E. s2 n6 E8 |/ ]9 {! w& u/ |$ h
    从文件编码的方式来看,文件可分为ASCII码文件和二进制码文件两种:
    : a8 ?2 L; T% x$ V/ l. s  `/ f8 l% OASCII文件也称为文本文件,这种文件在磁盘中存放时每个字符对应一个字节,用于存放对应的ASCII码。例如,数5678的存储形式为:   9 [! d2 o7 o# f  U5 R
       ASCII码: 00110101   00110110   00110111   00111000   
    * }2 M1 _3 r, {3 X( v                         ↓              ↓        ↓            ↓
    & e$ r& L! A( r0 u- P+ J  十进制码:       5     6            7       8   % @3 Y/ q2 B3 d1 q5 e$ W

    0 {! A* [% x' x$ \共占用4个字节。ASCII码文件可在屏幕上按字符显示,例如源程序文件就是ASCII文件,用DOS命令TYPE可显示文件的内容。由于是按字符显示,因此能读懂文件内容。: Y, T0 F0 Z" `

    & f- T/ n+ h6 e: ~; }. l: H二进制文件是按二进制的编码方式来存放文件的。例如,数5678的存储形式为:00010110   00101110 只占二个字节。二进制文件虽然也可在屏幕上显示,但其内容无法读懂。C系统在处理这些文件时,并不区分类型,都看成是字符流,按字节进行处理。输入输出字符流的开始和结束只由程序控制而不受物理符号(如回车符)的控制。因此也把这种文件称作“流式文件”。  
    4 I5 }  m* P8 \  g4 K. p
    3 V7 K0 h5 X" U( |9 T/ {) r2. 文本模式(textmode)和二进制模式(binarymode)有什么区别?  
    6 G8 _. ^  M$ T/ G8 b; m1 s4 g9 q( i% i
    流可以分为两种类型:文本流和二进制流。文本流是解释性的,最长可达255个字符,其中回车/换行将被转换为换行符“\n”,(如果以"文本"方式打开一个文件,那么在读字符的时候,系统会把所有的"\r\n"序列转成"\n",在写入时把"\n"转成"\r\n" )。二进制流是非解释性的,一次处理一个字符,并且不转换字符。
    % U; M( L0 R1 r3 _) Y, ]: M2 H. K5 _! K: o2 t3 z
    注:  
    8 }" f  n( U# K; ]* O$ o1 l; N# }  T! P
          \n一般会操作系统被翻译成"行的结束",即LF(Line-Feed)
    1 C/ c# M+ c9 G2 }+ b% n      \r会被翻译成"回车",即CR(Cariage-Return)
    . l5 A: M! N2 U/ Q      对于文本文件的新行,在UNIX上,一般用\n(LF)来表示,Mac上用\r(CR)来表示,
    ( u$ ^* W7 E3 s* M/ j3 t      Windows上是用\n\r(CR-LF)来表示。        
    % D2 h+ v3 |: r1 X6 k         
    5 X1 s2 m+ F6 l2 g    通常,文本流用来读写标准的文本文件,或者将字符输出到屏幕或打印机,或者接受键盘的输入;而二进制流用来读写二进制文件(例如图形或字处理文档),或者读取鼠标输入,或者读写调制解调器。如果用文本方式打开二进制文件,会把“0D   0A”自动变换成“\n”来存在内存中。写入的时候反向处理。而二进制方式打开的话,就不会有这个过程。但是,Unicode/UTF/UCS格式的文件,必须用二进制方式打开和读写。: g! j3 W5 `& O( j
    ---------------------------------------------------------------------------------------------------------
    2 v' [: B9 T$ R5 o6 S1 s/ J3 E8 m& q  V* A
    上述基础其实大可以略过,简言之,对用户来说:在 matlab 中存储成为二进制还是文本文件取决于fopen的方式,如果用wt,则存储为文本文件,这样用记事本打开就可以正常显示了;如果用w则存储为二进制文件,这样用记事本打开会出现小黑方块,要正常显示的话,可以用写字板或UltraEdit等工具打开。
    ) ?* G/ u7 F0 m( T- w二. 具体例子分析:
    3 S$ k# o2 K( z( z; R* N5 XMatlab网站用两个例子非常详尽地介绍了各个命令的基本用法,实际中,面对手头上的数据,如何选用合适的命令呢?以下结合几个示例给出一些总结,大家举一反三就可以了:7 N% O; b, Z9 H& O% b

    1 E# i6 D  t+ D7 ]( ?- w; z1. 纯数据(列数相同):  i, M* M5 \8 w) ^
    源文件:* ]: J: O' q. b) [8 L
      t* y1 z* F, p  L# I

    2 u, y& Q& g- Q  z4 ^6 L& {* B+ P, x' Q
    CODE:8 Y9 {" M" _4 {
    0 3866.162 2198.938 141.1403 @( n% L0 `$ X, v2 \
    1 3741.139 2208.475 141.252
    2 U. y  u: Z% `2 M2 3866.200 2198.936 141.156& @7 `- I2 b# z# ?
    3 3678.048 2199.191 141.230
    9 O) [! h' h3 a, f3 G6 O4 3685.453 2213.726 141.261
    4 u; ~& u1 {0 c9 i5 3728.769 2212.433 141.277+ S( r' S9 Y6 J2 P% y
    6 3738.785 2214.381 141.256
    $ q0 q5 S' r! b9 g' ~6 {/ K$ q7 3728.759 2214.261 141.228
    6 V& f+ s- d7 A! g/ U& W  y9 x* Z) }8 3748.886 2214.299 141.243
    6 W. n4 h1 `: P. H2 M: I0 E: |9 3748.935 2212.417 141.253
    9 Y4 I' A5 v! m' M0 E+ f& O10 3733.612 2226.653 141.2365 V6 \, a1 m1 N/ \4 e  {/ K3 U
    11 3733.583 2229.248 141.223; X$ _) i3 [$ b& w% x
    12 3729.229 2229.118 141.186" X4 R0 K. F; c/ _: X

    7 i6 P) e6 P* `
    ( p+ N5 b% y/ T. Y
      U2 w& r! u: g" |) m4 }( W; G
      \: [8 M, \, m解答:对于这个txt文件,由于各行列数相同,故简单地使用load,importdata均可。
    ; Z9 o& e& w3 |/ t, ~; ]# o! {4 M: ^, `! ]" m

    # A, ^7 Q! B6 a2.字段名(中、英文字段均可)+数据:9 j# _5 L3 y3 A3 V: l9 k$ W0 c
    源文件:
    / H# |1 V. L# ~$ y3 A' Q; C. b  e' B7 R( k' j
    " b" e) n0 A$ E0 a
    CODE:
    $ z! z$ a6 h  i$ N# k* Y4 J; VCH0 CH1 CH2 CH3& ~! z" k" K9 ^( M( C4 p9 h6 G
    0.000123 0.000325 0.000378 0.0005987 N/ [. s. `& r
    0.000986 0.000256 0.000245 0.000698
    2 D2 W; l! i8 T) a$ e2 ?
    1 C4 J8 t/ q* g, d+ `. @- t$ c5 f
    " D! H, V! o4 c; f0 e+ ]6 E8 V解答:由于是记录的形式,因此各行列数必相同(缺少部分列时请自行在文件中补上 Inf 或 NaN),故直接使用 importdata 便可。
    ; H4 P2 A8 z9 O8 k: O# C4 n$ `' Z7 c, p. s
    3.注释(含有独立的数字串)+数据(列数相同):/ c0 u3 M% P6 T3 t. D/ G+ ^
    问题:这个文件有4列,但前6行是文字说明,4列数字是从第8行开始的.现在我想把这个文件的前2列和文字说明提出来组成一个新的dat文件8 Y$ f+ `2 O/ g6 e; ^

    8 ^* F# M( I8 |. ]源文件:
    6 l% [- C/ Y3 N& t' j2 g7 R
    # l9 |8 V  Z$ ~# `2 M) A. f# I0 v- d, W! d8 v  y/ ^% I; L# G( O  c3 ]! p
    CODE:' G( B0 t5 A9 R
    Group 2  12.02.2006   Limei
    % t. Q7 b' l/ L# R- m0 @Samples of datas: 500002 B5 L6 x) x4 i- P  ~! E( y
    & E; n; m# c1 `* ^9 w8 e
    CH0  CH1  CH2  CH3$ }$ t. D5 c& w) {  r( {
    0.000123  0.000325   0.000378   0.0005980 m! |. f( Q( M, L7 u" i' _0 ]
    0.000986  0.000256   0.000245   0.0006983 U' N' H! ~/ _" }( \8 k

    4 m: n0 t+ [8 f8 P0 Q7 `, g
    $ b# o2 R' x0 u& k) ^( M目标文件:. O, S0 V! p# Z% i9 Y# n) O. y

    3 T' h5 ^5 J0 g& e0 @6 ]9 k/ ~2 j: Z
    CODE:
    ' r1 A6 x: J6 @/ `, h6 GGroup 2 12.02.2006 Limei
    0 X1 z! b& u5 L; Q) k# Y. M6 kSamples of datas: 50000
    5 ^' f. s9 s/ f6 ?1 ^6 K- N) y
    * \+ V! j" r. f$ R/ C  t0 ^4 g* k! RCH0 CH1
    , Z' |. |1 F* V7 [& T5 D" ~# L0 I0.000123 0.000325  t& U! N6 c- ]2 f9 c  E  g- l
    0.000986 0.000256
    " T& v9 J3 x) _  G3 l. c0 l) E  ~% U% n& c

    ; j% r6 ]) M9 x解答:由于注释中含有独立的数字串,且注释部分没有明显的格式,这时候用importdata, load等高级命令直接读取会失败,用 textread, dlmwrite 等格式化命令也不太合适,因此只能使用低级命令进行读取。(当然了,可以跳过注释部分直接用高级命令读取数据,即:[a b c d] = textread(filename,'%f %f %f %f','headerlines',4); )。一个简单的、非通用的包含注释的读取方法如下:
    ) c5 J1 N/ Y" h+ q) d-------------------------------------转 ---------------------------------------------------------------------------------------& }5 G# V% ^+ j8 j5 o, s& `' ^2 T% s

    4 e* p3 j, z) v) R- r3 o9 _CODE:
    & j3 P: u  F) ?clc;clear;
    * r" J6 Q- \- Efid = fopen('exp.txt', 'r');
    ' B7 D; `) r5 p+ [8 wfid_n=fopen('ex.dat','w');
    ' C$ ~; S6 x4 g# ~* ^6 E6 f4 Dwhile ~feof(fid)
    % O, @% J0 Y3 D: y0 r    tline=fgetl(fid);( n( G- t) n* ?) \9 K
        if ~isempty(tline)  O2 W& J7 \: l, f
            if double(tline(1))>=48 && double(tline(1))<=57  %数值开始
    : u2 F# [4 w' L. [' H0 S5 q9 e            a=strread(tline);
    * F  i( n3 t) g; {, D4 k            a(3:4)=[];
    , P2 n* R6 X* L( X; N            fprintf(fid_n,'%f %f\n',a);; {6 j* b/ Z6 X
                clear a;# {2 }& f2 P' s9 C4 y* a
            elseif double(tline(1))==67   %字母C开始- h) j8 X% `5 U; @# _
               [b1,b2,b3,b4]=strread(tline,'%s %s %s %s');, a) c% X. ~' {! C) w+ N( w! s5 v
               b=[b1{1},'  ',b2{1}];! Y- R" x2 \4 B" C( E# C& Z
                fprintf(fid_n,'%s\n',b);6 V( z% ~% W3 R
                clear b b1 b2 b3 b4;( V0 R. Q' D4 u
            else
    9 X2 T1 A( t# N7 e            fprintf(fid_n,'%s\n',tline);  o# k( a- M: ^( q1 i2 {' c
            end
    4 b; j5 [# S8 n' G! Y    else  G: ?) S6 R4 p" H. n
            fprintf(fid_n,'%s\n',tline);
    ) r0 _. t" g, }4 o    end
    : t  @0 C2 h- Q# v7 eend2 E5 j. B2 N; q1 o, h9 n; C' j
    fclose(fid);
    : g4 q" V2 x+ X% `% ]/ Ofclose(fid_n);5 u- O$ B  x+ H6 B: g
    " i# I9 N$ R9 [7 l# o6 M
    3 u, u( z9 {6 I0 j1 n
    ---------------------------------------------------------------------------------
    * y1 z3 y, U: z: o8 j7 L7 @) A0 e' R9 U
    4. 注释(不含独立的数字串)+数据(列数相同):* t7 a4 t0 O0 j) ]
    源文件:
    8 U$ O2 Q: F2 L6 y. U# X+ O/ }# m2 e9 ^. U3 H5 S
    CODE:9 D4 \+ w/ o5 |6 y/ P
    你好 abc2 F7 R$ X; k( U9 i0 ?9 G1 v4 K
    欢迎来到 我们6 {; |+ l% I4 i# r* w
    振动论坛
    , K$ j$ u  N: B, ?% s6 A. Rvib.hit.edu.cn; j$ w$ n. \2 Z1 h9 X" T
    1 11 111 1111
    ; `# ?$ w, M- |& \/ q7 L2 22 222 2222
    ! _6 t. t8 O0 @" y3 M3 33 333 3333# _5 _. B! Q$ Q/ O+ b+ `
    4 44 444 4444
    : z. x2 D( h0 B9 Q5 55 555 5555
    0 g( o3 r( E' H5 d. r
    . s- K, z/ o4 K1 ^* k9 F, e; q9 d$ I) q0 ]& G) ?- W- G/ S
    解答:直接用 importdata 便可- |. E1 Q; q. j! t; e5 [4 y
    + ~/ j0 J0 t% {4 a
    注:有时候注释中含有独立的数字串也可以 importdata 成功,不过得到的结果有可能不正确,建议这时候使用第3种情形的读取方式。* }" T9 r; h) O$ f
    8 \# q2 R7 G5 c" s
    5. 注释与数据混排:
    / q7 z7 m. v9 V" b对此当然只能自己编程,举例:  U- G5 B( o" L5 Q. Q4 l$ I% D

    $ M* @. v: S  S% d5 y源文件:
    & O" U/ N, ?- [% _
    0 ~  C: B: {0 QCODE:# F" w, L) h) c
    1 11 111 1111
    # p+ X! {4 A2 y& D/ Y你好5 G' O. H) i9 J' r! W/ h
    2 22 222 2222
    2 R$ t8 W; O: O) ?8 N欢迎来到
    % D& t" O2 H) ^3 |) h) L! g3 d3 33 333 3333) P* `+ Y  ?- _, W5 T8 U
    振动论坛
    ( i% r' G( F# R* N8 `" a4 44 444 4444* V# S' \( b8 w" r
    vib.hit.edu.cn$ Y( [! ?; E: ~- ?2 a" H+ M8 [3 J' }
    5 55 555 5555
    8 j& P' B9 |* b+ D- r- K- ~' A3 l3 L5 d4 [- C7 F0 c- j

    ( M. K$ q. Z, W- z解答:
    ! ?$ K1 f6 ^4 c* h4 H) w+ c/ s3 f& v--------------------------------------------转--------------------------------------- d% I( ^/ A( H

    . t) O$ X3 r6 s& g) P, P$ E5 V9 _' O
    CODE:  W! T# N; W5 s, o9 P7 m

    6 Z+ D8 w1 I' I  c+ ifunction [data]=distilldata(infile)- A* W' y* h, Z! C7 [) A6 y
    %功能说明:4 F- m8 i9 |) s9 T
    %将保存数据的原始文件中的数值数据读入到一个data变量中: {6 _. ]. X, P4 w2 j* w/ F
    %使用说明:- F# [! o2 R# |+ r
    % infile——原始数据文件名;, _1 b6 c3 l$ j- N/ }) ]
    % data=数据变量
    & j9 U8 G" S; y: X* J8 m
      F% }7 [! P! b. i: vtmpfile='tmp2.mat';3 w9 [* a9 y% o: m  J) Z
    " H7 \, w& [! ]6 ^
    fidin=fopen(infile,'r'); % 打开原始数据文件(.list)7 a5 Q+ a/ p! b8 [: l$ F9 k+ g/ t9 U
    1 m* Y" ~9 h: A; C
    fidtmp=fopen(tmpfile,'w'); % 创建保存数据文件(不含说明文字)
    4 d# [2 O5 K4 k- \
    4 m6 |. H# G+ Q) nwhile ~feof(fidin) % 判断是否为文件末尾/ @7 J) w  A5 k# I3 E3 P4 w
      tline=fgetl(fidin); % 从文件读入一行文本(不含回车键)
    + d# ~& h; Q( n& M3 m2 U* T" `4 P8 L+ P  if ~isempty(tline) % 判断是否空行
    % F/ x9 Q3 c; r3 N! X/ j    [m,n]=size(tline);
    ; ?5 z/ |& C. c3 _+ |    flag=1;/ m1 \  B( o4 J
        for i=1:n %判断一行中有没有字符(+-.Ee和空格键除外)' K* S. f4 ?- R: R
          if ~(tline(i)==' '|tline(i)=='-'|tline(i)=='.'|tline(i)=='E'...2 S8 `" I; R7 o: L4 ?5 o
              |tline(i)=='e'|tline(i)=='+'...
    - H1 B9 k7 r" F7 \5 W6 `: M          |(double(tline(i))>=48&&double(tline(i))<=57))
    * U5 v2 K  T* n' a# u' U& d9 m        flag=0;. m) g4 s, L+ A, g0 d
            break;
    ; |; ?, _5 J: W& A- |      end
    ) B# Q3 w7 r1 w: `    end! Y& f8 d9 G7 }# n" }
        if flag==1 % 如果是数字行,把此行数据写入文件6 H5 H( a! k7 s# G) d
          fprintf(fidtmp,'%s\n',tline);
    5 x  Z" |5 p; k: a( f& n    end
    5 c# k3 u( v/ o" l2 s  end
    ! m/ O; S1 c( j" X1 K" Nend
    ( D+ _7 [0 M  r& E4 V, q. d% K
    ' D; x3 m8 P0 [4 N) v  Hfclose(fidin);$ `4 ?5 a# }% ^2 @/ ~4 K8 o

    4 B  T. d# j6 M( t( n! c( @fclose(fidtmp);+ k2 W3 E( c* }/ ~0 G

    ( D4 T" C# Y& M: Udata=textread(tmpfile);
    ) ~! |& V& V2 W! Q' o& {( m1 s+ S) Y' N: ~  O' G
    delete(tmpfile);
    : d- s% }: Y* `6 d% V# ^
    , Y2 }1 ~7 V6 X9 {$ o; r/ x& C' @
    & \9 X. X/ p7 X7 E( o( k" t  z4 n2 \) @- h. L- @
    ---------------------------------------------------------------------------------------------------------
    2 j9 v* z% r+ w( V8 E; w; {另外,如果要求不高,也可以使用 textread 函数跳过注释部分进行读取,不过前提是需要事先知道文件内容的结构(即哪行是数据、哪行是注释)
    9 @  [+ L$ K. c" R, m4 z$ [+ j7 m. u4 T7 U: P! [1 l% P* h" l5 `1 Q
    6.各列数据的分离:' O# {, J! Z$ y. f
    源文件:
    # x1 J$ Z$ x: m2 U0 Q. q8 B7 {( a' q  z7 z0 |$ @/ ?* R
    5 n, A1 P& J! `3 B$ H0 U' T) N
    CODE:8 i# c  {, R6 f5 x2 B+ r- N% a
               0 +  47038.7   1.05  09:26:07  C
    ( e+ e8 r4 f# {9 k6 f; P. F           2 +  46477.7   1.03  09:28:38  C  ; |9 u1 A4 B+ l
               4 +  44865.7   1.04  09:28:48  C  $ W# ]. D6 T! S: t
               6 +  41786.4   1.03  09:28:56  C  
    ' v& q: Q3 y3 k% E9 v           8 +  39896.0   0.97  09:29:03  C  ) H, a& {' e7 S' E4 [
              10 +  37518.4   0.93  09:29:15  C  
    - t# X/ @- s. `6 l; [          12 +  35858.5   0.92  09:29:30  C  4 }2 `' J7 s" o# x. _6 l
              14 +  46105.0   1.03  09:30:21  C  1 u+ W. W& k" J9 L
              16 +  46168.6   6.89  09:30:30  C  
    " g. W1 q% e* z          18 +  48672.3   4.33  09:30:40  C  
    3 ?& l8 T  S5 s, V4 o' Q1 ?: R          20 +  49565.7   0.49  09:30:48  C  
    1 W# }/ o7 y" {5 F          22 +  49580.7   0.53  09:30:55  C  
    % N  Y5 J: [0 w" T          24 +  49602.3   0.84  09:31:03  C  $ X( e4 F1 p9 D) y- [2 R
              26 +  49582.5   1.51  09:31:11  C  
      X1 U3 a! J+ D' Z! }$ z          28 +  49577.0   1.39  09:31:19  C  9 ^  s* A6 n0 R9 s8 @
              30 +  49589.3   0.61  09:31:27  C  
    2 ~. [1 G7 i5 o5 j: @, P          32 +  49578.3   1.06  09:31:29  C  ( }, b% g* R" m" |( S! n! A
              34 +  49512.5   1.77  09:31:38  C; A. f# w% u' X; h
    : C3 s: q1 D! ^! t! x0 m
    6 W5 o9 m2 }$ e$ J) I" i% i. S5 d

    * {9 w% a2 {. l" b$ [5 |+ J+ _1 J) K) [( }/ X! y$ l9 y
    解答:直接用 [a,b,c,d,e,f]=textread(youRFilename,'%d %c %f %f %s %c'); 便可! S3 c- r% @" G0 {5 W8 p/ q& S" q

    * Y+ g; K; n3 N; f4 N% e5 d' B' }/ d( `  X( J% P+ P
    三. 注意事项:4 M8 R0 O$ l  T

    & m/ G+ I* p: \; B9 P  T
    9 C5 t" O1 `. d/ b1. 请在 matlab 中保持当前路径在该数据文件对应的目录下进行存取,否则,存取时请给出该数据文件的具体路径。
    5 t& u6 r( Y; ]5 ?
    7 Z* S. a; Y9 ^4 A( F$ c1 \+ V2. 存取时,请给出该数据文件的全称(包括后缀名,读取mat文件时可省略)9 {$ M4 q1 N5 k

    2 }) ?( _" b5 i. d$ |5 c3. load data.txt和A=load(‘data.txt’)的区别请参阅精华贴:
    . G  F% ~+ a: Q
    0 B4 M. r' H0 U9 D5 [6 J* I( y/ \4. 请根据读写需要来打开文件,即根据你的需要来指定 fopen 的 permission 属性为读或写。如果只用 a 进行写入,就不能用 fread 读取。此时应该写完关闭文件,然后用 r 打开读取,或者直接用 a+ 进行同时读写操作。否则,会产生莫名其妙的问题!以下代码是一个错误的例子:( I; U/ Y5 O5 w8 \2 `7 y4 [% O

    + T$ c8 ~$ j5 K4 a, }9 N6 c
    . M# o7 H& I& W# d# TCODE:
    6 q  }; P. E: F) x2 F1 D( d) p7 o! t) X0 M' a  G! ~
    filename='e.dat';$ J4 f3 F2 D: c( ]
    fid=fopen(filename,'a');' t% g* c9 y# B* W' ?
    if fid<0  J' p. ~% }+ [) u, q
        error('fopen error');+ p3 ^$ O* M/ T8 B/ ]9 Y* ]
    end
    # T! w, T0 ^2 W  Es=[1 2 3 4;5 6 7 8];* J5 s" ]2 T  O7 ~' Y9 ?
    fwrite(fid,s,'float32')
    " l: D7 {, i- Y[dd ll]=fread(fid,inf,'float32');%把t中的数据全部读出,即s矩阵。( _# y; e  C2 h  n
    fclose(fid);, ^8 u9 N; _+ z
    " d$ J0 Q5 d* n0 o) D1 H; R
    3 W* I$ o4 i3 [

    1 T0 h2 T9 f' n) a+ u3 T: ^. E! o: Y

    ( |' N# f" S8 U# V% q: \此时得到的dd, ll 是错误且无意义的!
    : I6 V1 ?: L: p; d3 |& \$ [6 a. b% E( {- o* {
    四. 其他相关问题:$ G/ O6 g, R8 s  v2 B& Z- t

      p$ u3 }, g9 {/ b% O% T. S1. 连续读取多个文件的数据,并存放在一个矩阵中:; b% _7 B9 d  g) N
    (1) 首先是如何读取文件名:: l! r( f. ?6 _' D/ C
    方法一:
      L6 H2 }: ^2 d/ d0 ?filename=dir(‘*.jpg’);5 ~+ \- e5 r/ h! _) C
    那么第i个文件的文件名就可以表示为+ W" I3 D' L, v, D0 D
    filename(i).name" K8 x* ^( q7 D# @5 G: T8 ]/ ]
    文件数量为:length(filename)1 b/ V1 s9 `: a& r6 }% x
    4 z8 g7 M* R8 z' c
    方法二:
      F' a& y0 U" N! x! [$ z先在Windows的 MSDOS(命令行)中使用以下命令生成一个list.txt文件:# W1 \7 L, B5 I. }+ O: ~

    8 y! T. c$ E+ F6 ?; J
    $ I+ W& T+ J0 h* g8 c. X5 t; j5 r7 xdir path\folder /on /b /s > path\list.txt+ a( s7 d, N  ~. x) m
    : `% q/ w/ {3 t$ I% G( a% o8 O
    举例:dir d:\test /on /b /s > d:\list.txt
    ) X& T+ |1 ]% y
    7 G* p# G' ~" n: a( @1 n4 H4 h( ^' I然后在 matlab 中使用:
    6 E* `2 [( a* {; o1 B8 {, w
    - u- \  k1 b/ ?% |+ y4 j& Ffilename = textread(sFileFullName,'%s');: Z* W" y! Z: S1 v: H

    ; n: r( e. `, u2 d2 e* S4 b把所有文件名读取到list细胞矩阵中,最后对filename{i}便可得到各文件名。$ \' j5 w( ?, [" `1 U. m: a
    8 v* d7 {$ m; _3 u7 D9 D: @; }
    (2) 然后是读取文件名的数据并存储:: x" V/ M, X/ M- y8 j9 B- w
    假设每个文件对应的数据是m*n的,则:4 {; o. L0 v2 J# T5 h
    / j8 H0 q) L7 f7 q! ], d
    CODE:; t# `# S7 n6 O9 n% R" D
    k = length(filename);, `" m& Q6 h) I: J6 f
    4 A  \! J( }4 W' B+ y
    Data = zeros(m,n,k);& N* u0 t1 `% h( v% |, f8 v4 k
      q7 M! ]) w5 N* T
    for ii = 1:k
    8 m. [. m% |) G+ |  Data(:,:,ii) = yourreadstyle(filename{ii}); %yourreadstyle是对应的文件读取方式的函数
    ) o# S3 F) a: {2 aend
    : d+ s1 {# }  o$ h* m: c
    * Z! q& ~4 ]2 G0 H7 l% ~
    ; _/ P' w3 U7 u( T+ l9 [/ Y2 G% Q6 p6 ?% F: R$ l; m

    # Y7 y( G" _$ r9 g9 G$ z+ z2. 连续读取多个文件的数据,并存放在多个矩阵(以文件名命名)中:
    1 E: A% I. w$ z假设每个文件对应的数据是m*n的,则以上述第二种文件名读取方法为例:" p. C7 F% i' u0 z
    0 \" m9 S/ e' v3 ?- p% ]8 ?
    CODE:0 N8 z. n- p" h0 I: U1 e9 |# v
    k = length(filename);8 ^' q# m9 o# f# v  \
    for ii = 1:k
    4 E; e2 g7 c4 R. I; R! N9 |  D = yourreadstyle(filename{ii});
    5 ?, O& e0 h' P& O+ |3 @1 ^1 ^eval([‘Data_’, num2str(ii), ‘ = D;’]);" A1 b6 j' d' `* V  n" y/ o) G
    end
    . W1 m4 w% `0 _- B1 s0 h. J' h! O

    % g1 U: ^$ e+ \! z% u( o" C- L
    , A4 x& ^, R4 D& H0 ]4 S! d3. 文件名命名问题:; i4 G9 g5 M1 c4 p2 Z* B
    文件名为 abc00001,abc00002,... abc00009,abc00010,... abc00099,abc00100,...abc00879.  准备把这些文件名给放到一个数组里面去。/ s; v# Y- y- ^9 v! B) B

    1 d: `# y0 I; U, a8 P0 \解答:5 t' x- U+ h7 l" A: \% `0 E
    4 J# |2 \* f; O8 T: c9 P
    CODE:
    + H  R7 ^: f* k. q- o6 x2 ja=cell(879,1);
    & q0 o+ a# S, j" @. h' \for k=1:879# F3 |; P" x$ v& O( d
         a{k} = sprintf('%.5d',k);
    " `  t6 ~, G! g% U) B, v! Zend/ j! }8 W0 E5 Q- b

    ( z1 D$ X* ~4 n- d( T5 o1 Q" Z, `5 m$ s* G% U. `$ Q1 i1 I
    4. 上述各种文件格式、类型自动识别问题:可以利用正则表达式来处理,使之通用性较强。例如使用以下代码可以自动处理上面提到了例1到例5各种情形,不过由于存在自动判断,对某些例子(如例1)效率自然要低一点,而对于另外的例子(如例3、例5)效率估计要高一点(少用了一个循环)。
    2 M; y0 \& ^  E- Y) m1 H  u/ @( U  w
    - u$ T/ N' H. A: ?8 A3 I; u
    CODE:
    9 W: a6 ~+ }4 y; V: F* E; n( e- j0 {* b
    function [data]=distilldata_eight(infile)* Y6 t: w) B. S, I/ W
    %功能说明:8 ~/ r- `0 M, J4 l5 I+ }
    %将保存数据的原始文件中的数值数据读入到一个data变量中(自动判断数据行)
    4 O5 Q# U/ q  x! d%使用说明:! }) o& s3 \: C
    % infile——原始数据文件名;9 N( y# O- _/ `$ j+ [
    % data=数据变量; m0 C7 z) o7 h8 S; B, i7 o2 V4 d

    & x8 B. ~& p" A7 [5 a" r; xtmpfile='tmp2.mat';+ C; S) ^( E- q+ H: m

    ! D% I: L7 L2 P: ]! qfidin=fopen(infile,'r'); % 打开原始数据文件(.list)
    : `/ M* Z! G: [' i6 B/ U$ k* Q( Q- M. ?
    fidtmp=fopen(tmpfile,'w'); % 创建保存数据文件(不含说明文字)5 m, y' w3 f+ e
    5 e5 E4 h  _- S# e* B
    while ~feof(fidin) % 判断是否为文件末尾' H$ j7 Q4 r$ {8 h( f/ I: d
      tline=fgetl(fidin); % 从文件读入一行文本(不含回车键)4 N4 P! _" i7 r  J* p! w
      if ~isempty(tline) % 判断是否空行8 h9 F. i2 d1 t. ~+ m2 d
        str = '[^0-9 | \. | \- | \s | e | E]'; %正则表达式为:该行中是否包含除 - . E e 数字 和 空白字符 外的其他字符
    4 ^4 |. `( W! ~9 ^$ B    start = regexp(tline,str, 'once');
    0 I" @, ?. S/ u0 p) f# t* ?    if isempty(start)
    # D* H! ~0 ]1 E) B9 J      fprintf(fidtmp,'%s\n',tline);7 [; X, `/ g6 D& X! f
        end' f0 `1 G$ V  P/ M
      end$ p; j" H8 t0 t% F# e. u; m) V! n
    end2 |, k2 l6 X- G, U. y

    - C+ X% X3 O( X. ~* efclose(fidin);
    1 Y* H6 e# H. K
    0 d1 ^! @# s3 i+ C" P/ i& {fclose(fidtmp);
    $ Y! ]$ A- ^1 H! J0 r% y7 S- d0 k
    data=textread(tmpfile);0 X- }0 ]( K* \  Y

    7 X+ T3 R! s, y4 g( Ddelete(tmpfile)( c& `( t  W+ w( N2 f' d
    0 J) V9 L& _& [

    1 N! A& z! |6 J* U" m4 t% E  R8 i: S  Q
    5. 大量数据的读取问题:
    $ ~1 ?0 O8 O: D4 H/ g可以考虑使用循环分批读取(特别是在各数据是独立的时候),或者使用稀疏矩阵来实现。另外,也可参考《深入浅出MATLAB 7_X混合编程》一书第一章% G$ u7 V! Y) h+ t+ R
    - ?; P: t  ~9 V9 z' Z, ]
    6. 读取整个txt文件的内容(获得文件中的所有字符):
    # |3 `; x; I- l2 t6 b8 @- X0 C6 W2 O. U8 t
    CODE:
    4 L  N9 J  l6 s6 g( c# f/ N3 l  S( f+ O3 H; O/ J7 k5 h+ D  a/ ^8 ]
    f = fopen('yourfilename.txt','rt'); % t 属性根据需要可省略6 n  e7 r. Y/ l  ~
    x = fread(f,'*char');& O* \2 V$ ]' X, R* G
    fclose(f);; j% N* |3 K8 H) m9 ?7 B

    + ^( \; r7 {3 f* o* L" s  F3 u  q
    + }4 Z6 m7 t$ b6 E6 U3 }# t& ^/ Z$ J7. 把维数不同的矩阵及其变量名保存到一个 txt 文件中,例如 a1 = 123; a2 = [1 2 3;4 5 6] ,希望得到的 txt 文件如下:  _0 b8 p/ ]+ K0 X

    $ e# C0 g' L& b  \6 O) L
    # I$ T: s- n/ y* _' }QUOTE:
    5 i2 K# W8 X7 h
    7 H) O9 r" V$ M0 a/ ?& B/ \7 c# }7 La1:5 [: A1 ?/ `3 t
    123
      c4 l' f. m9 n4 n! s$ ?a2:
    ( N4 Y1 G# q# F, N$ f1 q1 2 39 W' Z5 U8 y" v8 q- K! `
    4 5 6
    " @9 f# A* u- J% l( J" u( Z
    . H, ]! u0 k0 D( o& J. }
    * ^0 h# S- f, M7 C5 m+ e2 {# _
    0 m! P. k6 A7 ]  z8 H' s/ `/ |. C1 Q1 I& G0 ^" c$ X8 a* o

    6 z0 z/ z9 ^* s* p# E9 ]) y+ K如果写入的时候简单一点,则可以采用以下方式,不过读取的时候比较麻烦:5 W2 w, ~- k2 U
    ) B& _" k5 S2 f- E' k
    CODE:
    - N$ W8 H( l, v" a; Q% v0 j* x7 y; @6 A# ~  B
    a1=123;
      @' s- z& {; ba2=[1 2 3;4 5 6];
    7 E4 w6 N: A5 Y( I/ c6 A& d* lfid = fopen('myfile.txt', 'wt');  D! }. @; g; P9 M; K' s; o* f9 O
    for i=1:2  g$ S. ?4 l& j$ s5 p
        fprintf(fid, '%s: \n %s\n', ['a',int2str(i)], mat2str(eval(['a',int2str(i)])));
    2 b2 [! w* \0 T4 H0 \% Yend0 d0 F% w% n$ _5 P
    fclose(fid);' l% j, b3 F3 t0 W$ H

    & Y% s: n' D- T) V- N9 f) P3 F
    0 Y% A8 R3 _) x相反,如果写入的时候复杂一点,则读取的时候会简单一点:" W' ^7 Y; j% @4 @9 _

    / |1 n5 c$ s; j- X* ]; r: KCODE:
    " }0 ~* v5 @9 g/ H1 F
    # l0 A; O& R: Y2 \. `2 E% {a1=123;
    & D. w; ]) k; ?/ C6 ]a2=[1 2 3;4 5 6];
    , K# X/ W! M+ m. W' l/ pfid = fopen('myfile.txt', 'wt');
    6 M9 V8 W: v8 {2 d0 p8 Z* Tfor i=1:23 h, A  M4 f3 G: Q0 o1 L9 N$ e3 M6 j( I
        fprintf(fid, '%s: \n', ['a',int2str(i)]);0 X6 l# X$ B" m1 M/ e
        b = eval(['a',int2str(i)]);
    . q, N/ e) U+ k- _  {    fprintf(fid, [repmat('%d ', 1, size(b,2)), '\n'], b');+ M% s) ^0 O9 a9 X; j, F
    end3 \1 C4 M" \8 V+ v3 g. E2 _
    fclose(fid);

    该用户从未签到

    2#
    发表于 2020-11-24 17:38 | 只看该作者
    文档读取技巧教程
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-6-20 18:58 , Processed in 0.109375 second(s), 23 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表