EDA365电子论坛网
标题:
#技术风云榜#转一个网友分享的文档读取技巧教程
[打印本页]
作者:
MOTOACE
时间:
2020-11-24 15:54
标题:
#技术风云榜#转一个网友分享的文档读取技巧教程
转一个网友分享的文档读取技巧教程
( O; u+ b. g! z: V5 ~* K# [# O6 A
; s. O8 Y6 q, q$ p. T
由于大家在 I/O 存取上以 txt 文件为主,且读取比存储更麻烦(存储的话 fwrite, fprintf 基本够用),因此下面的讨论主要集中在“txt 文件的读取”上。除了标注了“转”之外,其余均转自技术论坛。
! a/ M5 d6 S; R' X" ^1 ~0 m
% S: t1 A1 `3 q5 I& }% q
一. 基本知识:
$ G$ R3 |! _% ]0 v
--------------------------------------------------转----------------------------------------------------
, [- D5 `7 ^- C2 U, C
1. 二进制文件与文本文件的区别:
" t' R" a4 H# C1 x. L4 F
将文件看作是由一个一个字节(byte) 组成的, 那么文本文件中的每个字节的最高位都是0,也就是说文本文件使用了一个字节中的七位来表示所有的信息,而二进制文件则是将字节中的所有位都用上了。这就是两者的区别;接着,第二个问题就是文件按照文本方式或者二进制方式打开,两者会有什么不同呢?其实不管是二进制文件也好,还是文本文件也好,都是一连串的0和1,但是打开方式不同,对于这些0和1的处理也就不同。如果按照文本方式打开,在打开的时候会进行translate,将每个字节转换成ASCII码,而以按照二进制方式打开的话,则不会进行任何的translate;最后就是文本文件和二进制文件在编辑的时候,使用的方式也是不同的。譬如,你在记事本中进行文本编辑的时候,你进行编辑的最小单位是字节(byte);而对二进制文件进行编辑的话,最小单位则是位(bit),当然我们都不会直接通过手工的方式对二进制文件进行编辑了。
- I- z$ ^# k. O, W: ~
0 L& Y8 }1 w' I: ?" A. `8 d: c& h0 }' e
从文件编码的方式来看,文件可分为ASCII码文件和二进制码文件两种:
9 w+ y1 Z' x* a: o- k) @4 W1 k2 `5 w
ASCII文件也称为文本文件,这种文件在磁盘中存放时每个字符对应一个字节,用于存放对应的ASCII码。例如,数5678的存储形式为:
4 {/ w) q* Y4 \) @- m+ r
ASCII码: 00110101 00110110 00110111 00111000
# p) D: A: Z* h# o
↓ ↓ ↓ ↓
! I4 X4 M0 M" m9 t+ I n8 e( { Q9 o7 F
十进制码: 5 6 7 8
! F! {) @. j( c# t
a0 B4 T5 ~& r/ H( X7 w1 f5 v$ C' e
共占用4个字节。ASCII码文件可在屏幕上按字符显示,例如源程序文件就是ASCII文件,用DOS命令TYPE可显示文件的内容。由于是按字符显示,因此能读懂文件内容。
1 ?( _( c- F6 ~8 @/ ^/ q; k) V4 A
: J* h& I- G# U7 f
二进制文件是按二进制的编码方式来存放文件的。例如,数5678的存储形式为:00010110 00101110 只占二个字节。二进制文件虽然也可在屏幕上显示,但其内容无法读懂。C系统在处理这些文件时,并不区分类型,都看成是字符流,按字节进行处理。输入输出字符流的开始和结束只由程序控制而不受物理符号(如回车符)的控制。因此也把这种文件称作“流式文件”。
7 T3 [) M G2 J3 k' V
* g0 b( E8 n! l2 t9 D
2. 文本模式(textmode)和二进制模式(binarymode)有什么区别?
3 H& ^' F" K' m
# R# Q# @* l8 F
流可以分为两种类型:文本流和二进制流。文本流是解释性的,最长可达255个字符,其中回车/换行将被转换为换行符“\n”,(如果以"文本"方式打开一个文件,那么在读字符的时候,系统会把所有的"\r\n"序列转成"\n",在写入时把"\n"转成"\r\n" )。二进制流是非解释性的,一次处理一个字符,并且不转换字符。
" [$ L+ r% \1 S4 L: V0 }
! h. u- M" f% U7 [
注:
' m% T( c6 W# q
& g4 T4 L: v2 {& U7 o
\n一般会操作系统被翻译成"行的结束",即LF(Line-Feed)
! s! N- W* T9 G2 ]! A$ s/ v, |
\r会被翻译成"回车",即CR(Cariage-Return)
" J6 E8 w" b' }
对于文本文件的新行,在UNIX上,一般用\n(LF)来表示,Mac上用\r(CR)来表示,
* r! g4 ` E7 j/ J
Windows上是用\n\r(CR-LF)来表示。
) M0 z$ a0 y, X o/ D; r7 I
0 L6 l: u- C9 T9 L- q% ^+ q
通常,文本流用来读写标准的文本文件,或者将字符输出到屏幕或打印机,或者接受键盘的输入;而二进制流用来读写二进制文件(例如图形或字处理文档),或者读取鼠标输入,或者读写调制解调器。如果用文本方式打开二进制文件,会把“0D 0A”自动变换成“\n”来存在内存中。写入的时候反向处理。而二进制方式打开的话,就不会有这个过程。但是,Unicode/UTF/UCS格式的文件,必须用二进制方式打开和读写。
) k% S& A7 B& a& E5 A
---------------------------------------------------------------------------------------------------------
5 m S G' K- c, i6 R8 \
- a- |6 O) ?0 \! r% J( J# t
上述基础其实大可以略过,简言之,对用户来说:在 matlab 中存储成为二进制还是文本文件取决于fopen的方式,如果用wt,则存储为文本文件,这样用记事本打开就可以正常显示了;如果用w则存储为二进制文件,这样用记事本打开会出现小黑方块,要正常显示的话,可以用写字板或UltraEdit等工具打开。
0 A; z% n" e* O& I' k
二. 具体例子分析:
: c& L( ^; Z! E& E/ ]
Matlab网站用两个例子非常详尽地介绍了各个命令的基本用法,实际中,面对手头上的数据,如何选用合适的命令呢?以下结合几个示例给出一些总结,大家举一反三就可以了:
; D& B) W# ?) j0 s
2 O1 F, x* a& }/ B
1. 纯数据(列数相同):
. B# M4 P0 O! O% W# V
源文件:
" W2 v _& l& x* d% l
( X9 ^0 E/ j' A% Q2 c
( e; B2 l6 U' H8 |4 t
4 H4 O3 h. d; c: F, [
CODE:
# ^6 o# {' l( W7 ]
0 3866.162 2198.938 141.140
4 G. y; \. C& E4 k! E- Z
1 3741.139 2208.475 141.252
9 f9 I1 g. h$ K: E- {7 c
2 3866.200 2198.936 141.156
7 Y' g8 t# a. G2 H
3 3678.048 2199.191 141.230
7 O+ T6 A m* ]8 D0 m6 B, d8 m
4 3685.453 2213.726 141.261
; B1 o9 P3 l2 h- ^. v! Q/ T$ p
5 3728.769 2212.433 141.277
. C( |6 q# ~; H- U2 I/ h; ?
6 3738.785 2214.381 141.256
0 U/ E" w4 D( S
7 3728.759 2214.261 141.228
5 f" }: q. R5 I, N$ k+ I
8 3748.886 2214.299 141.243
- v5 ^9 M- Y, [$ v6 F( \6 C2 ~
9 3748.935 2212.417 141.253
% B% L" G2 `+ K/ e
10 3733.612 2226.653 141.236
h t6 m0 c/ t2 ?3 t: }; m2 N1 k
11 3733.583 2229.248 141.223
- S# b7 O" c: l( \* y* z0 h0 W
12 3729.229 2229.118 141.186
6 G* d9 X$ g. D4 ~3 B6 {# Y
) {# N9 r# I# Z/ ?( t- n8 a
- Z( l1 E, N4 y' ?1 @1 J
* B; C. x3 B5 r$ L3 @
k# f- u% I6 w! W5 @+ F
解答:对于这个txt文件,由于各行列数相同,故简单地使用load,importdata均可。
k" n. ^: D6 V0 r. O# {; K* K7 O
. X) V( N9 F9 V9 Q" B
; t6 _5 b9 k- h4 T+ |' D
2.字段名(中、英文字段均可)+数据:
# ]* |- A: U2 K; \" f
源文件:
- H" S9 g; [6 F- z7 m4 H# z6 b
$ X/ @# c, }0 {5 y& W. P& K9 b
6 g3 D; f. N* V/ O
CODE:
! w C: A h) N3 a" {# ]
CH0 CH1 CH2 CH3
9 f" O1 X% o3 J* Q
0.000123 0.000325 0.000378 0.000598
. A. t$ M2 J ? C$ A2 s
0.000986 0.000256 0.000245 0.000698
: _% G7 t) B4 g! p- x1 j
4 C6 @" R3 l7 m
3 N. @* M s! e. J- n' d
解答:由于是记录的形式,因此各行列数必相同(缺少部分列时请自行在文件中补上 Inf 或 NaN),故直接使用 importdata 便可。
, Q+ C2 _- b% r: g1 g" q
! C: H3 o6 K! w) K0 f: b7 \' l
3.注释(含有独立的数字串)+数据(列数相同):
/ k" S1 p$ x$ k0 t) s6 T
问题:这个文件有4列,但前6行是文字说明,4列数字是从第8行开始的.现在我想把这个文件的前2列和文字说明提出来组成一个新的dat文件
- F' g: w* O+ ]7 Z/ I9 n9 L
, f2 D0 U+ G/ S/ J) Z4 M& C
源文件:
1 w' t U# j4 J
2 p) x6 Y* @6 E8 I7 k" s
/ \8 h' C0 \9 L* ?9 E$ y/ q, }
CODE:
' I* Z4 Y$ Z& J/ c& X6 Q+ u
Group 2 12.02.2006 Limei
+ i4 w4 l3 n, |+ B) o2 @
Samples of datas: 50000
5 [5 ^0 U: A M: l( N9 [$ n
6 l E. T" Y% D9 @' c N! Q
CH0 CH1 CH2 CH3
3 h W" D" ^' g
0.000123 0.000325 0.000378 0.000598
1 U6 t3 F/ A* L3 i3 V5 p
0.000986 0.000256 0.000245 0.000698
, {5 g. f& W) Q0 E( M' O
0 } h( ?0 J# T9 }# G
/ ?5 X& W/ m0 A& {6 A
目标文件:
" m9 x% o0 G' B+ N5 F& Z) L- |
' A3 i# y G7 p% c/ S2 D; a9 h4 M% C
) G4 u9 f6 T |' m: e
CODE:
+ _2 S' w1 q& P. t4 h+ {. }* X% m
Group 2 12.02.2006 Limei
+ Q: K3 b: k" X y z2 A
Samples of datas: 50000
0 {* i3 s3 d9 E/ [& Z
( ]; P5 C$ B9 v3 H
CH0 CH1
, Y n! r+ G6 w. Y! D6 m$ Z$ k: D
0.000123 0.000325
, L, c' ~8 H- `2 p
0.000986 0.000256
, u& g# l) E6 n4 F$ ? z8 D! B
' K1 G7 `, n8 D! D' _0 Q/ p% ^# Y% l
/ @* T$ \4 ~/ W* w
解答:由于注释中含有独立的数字串,且注释部分没有明显的格式,这时候用importdata, load等高级命令直接读取会失败,用 textread, dlmwrite 等格式化命令也不太合适,因此只能使用低级命令进行读取。(当然了,可以跳过注释部分直接用高级命令读取数据,即:[a b c d] = textread(filename,'%f %f %f %f','headerlines',4); )。一个简单的、非通用的包含注释的读取方法如下:
0 B! ~$ Z, q2 E& `. v
-------------------------------------转 ---------------------------------------------------------------------------------------
. A, ?" x" |% e+ i6 p
) {+ v/ O/ T0 Y, W4 y4 r
CODE:
$ h: z8 L3 y. ]0 ]" o& z# l9 e
clc;clear;
4 z0 [: r- x+ v8 r: j
fid = fopen('exp.txt', 'r');
- r, E a5 R& `8 x6 E
fid_n=fopen('ex.dat','w');
) q( f4 B* y# z6 e( b
while ~feof(fid)
6 N4 I" q) I8 [% B J' Z% ]2 M, m( m
tline=fgetl(fid);
/ E3 I7 |+ _, n# X& I' `
if ~isempty(tline)
. ]( T1 |/ {$ y2 S) [5 ]8 m# K
if double(tline(1))>=48 && double(tline(1))<=57 %数值开始
% O' K }2 x6 ]6 w: o( q% d
a=strread(tline);
. Z$ s" ?: G1 O% }: r2 ?6 t O" m
a(3:4)=[];
& m$ ^' a; Y; L
fprintf(fid_n,'%f %f\n',a);
+ f) J: Y Y: N* d r3 X% D
clear a;
9 r; k/ J* V: K# }% H+ x
elseif double(tline(1))==67 %字母C开始
0 W. z" `& b" K7 K
[b1,b2,b3,b4]=strread(tline,'%s %s %s %s');
9 S3 M6 b2 O7 M0 J3 z, _. u2 P
b=[b1{1},' ',b2{1}];
! }5 R8 @4 M5 z4 t5 j4 O
fprintf(fid_n,'%s\n',b);
8 E Q3 q1 m4 T0 [
clear b b1 b2 b3 b4;
7 d+ |7 P* U' A( ^. K
else
% ^& `: n. U% t6 T4 m
fprintf(fid_n,'%s\n',tline);
- |( [ o' [; [( X& J) _
end
+ t) f0 Z# U% x' T: w& ?
else
5 Q3 Z% _4 i! V; p
fprintf(fid_n,'%s\n',tline);
5 b7 h2 F1 [" n) M" p$ W/ U! C
end
7 ?$ c8 o, Y" v' m6 N
end
H1 M5 @) r2 D) a$ N1 y
fclose(fid);
7 Z& J" T) P4 Z4 G3 n# B* a" H! F
fclose(fid_n);
5 A" ?2 h- I( j" b: c" L4 j0 A
: K e5 o2 P8 D/ A4 v) p; |) J
# B- D6 q4 f6 P" Z: p0 t4 V
---------------------------------------------------------------------------------
5 n4 l5 {# i5 m0 u4 [; A6 Z) i
7 E" Z- P+ v6 s' A1 B1 H/ Y
4. 注释(不含独立的数字串)+数据(列数相同):
# i( G f( q1 X8 q; }. [
源文件:
6 G/ h7 t7 p4 B" T
2 i) D% a7 l% p# T0 I9 y
CODE:
4 F1 e' `: a5 O4 E5 E/ P1 l
你好 abc
. i& q2 A# z* n+ N
欢迎来到 我们
: w7 c2 s6 g9 D: w# Y7 @& E8 H
振动论坛
. h/ z6 D+ f" m/ o. E) j- T
vib.hit.edu.cn
0 s% o! ]. a! T6 M
1 11 111 1111
, e* \" H. D; U# t& H$ j
2 22 222 2222
- P4 H8 m" g' t! q4 P
3 33 333 3333
* j5 F& P2 ^! M& L8 o% L" d
4 44 444 4444
+ O' i8 H" G! m7 {" q
5 55 555 5555
! @" S& H- ] Y3 H. v
# Y+ b3 n7 r6 ^: x
3 D! o7 T" S5 m' ]0 \; ]* e/ J4 p
解答:直接用 importdata 便可
" I. h: j' u9 k
]$ }2 h! i$ F9 U
注:有时候注释中含有独立的数字串也可以 importdata 成功,不过得到的结果有可能不正确,建议这时候使用第3种情形的读取方式。
! Q" }9 i( i; K; y
6 z) g! O; o. z2 m: J6 x+ a4 Y0 }
5. 注释与数据混排:
0 \9 c" q5 [# @' z% s
对此当然只能自己编程,举例:
# Z0 k6 H3 o" b- K. e8 E; O* |
3 h" J! T& e- n+ e
源文件:
' N3 E3 C: E- w6 O9 o
# A& ~8 \( t: L0 Z. E; W& E
CODE:
" w8 h" M }$ I
1 11 111 1111
, t) n. ^2 M# F
你好
7 d4 X6 Y: j9 h; h# n
2 22 222 2222
* X0 t- s, J v3 c9 `7 o3 _, i
欢迎来到
& s! M5 o3 Y N7 Q+ O& l+ F( o
3 33 333 3333
0 Y* Z, w' m, s8 a Y9 x
振动论坛
) e8 A3 D0 |4 u9 e% Y9 h6 t
4 44 444 4444
9 A& w c% _) r L
vib.hit.edu.cn
" q: g4 F# U; ]. X9 `7 Z
5 55 555 5555
5 Y3 k9 \- F% Y- _; D% u
$ z. y; }- i% @ _
1 }+ c* ?4 I+ N8 \
解答:
. r2 p. ?1 K% @; r- }9 l
--------------------------------------------转--------------------------------------
Q4 T$ a+ z: m
3 J3 {: W1 j4 x; ]( M B
! s9 L1 x! ?- m, \
CODE:
8 z+ E5 b9 U" J3 F% ]6 [
+ c( F9 F& B, t" I
function [data]=distilldata(infile)
* q' i8 n* n$ |/ T6 @; ~( z
%功能说明:
6 J1 s. W. J! m
%将保存数据的原始文件中的数值数据读入到一个data变量中
; g8 B* w9 n/ s# N5 o7 F2 J' F
%使用说明:
! {0 o* `" A7 Z
% infile——原始数据文件名;
: v8 S& b5 @% S. z; H
% data=数据变量
- [" d: }# Q& k( @. R9 ^( C0 m
" l! m+ q% M% \) c% k
tmpfile='tmp2.mat';
5 [: A; S! i8 Q, x
2 R: K- P( G5 |8 `8 a* X5 U
fidin=fopen(infile,'r'); % 打开原始数据文件(.list)
0 t+ j# {8 z7 H9 S$ K+ l U
8 S$ M' E- _3 H7 ^- j
fidtmp=fopen(tmpfile,'w'); % 创建保存数据文件(不含说明文字)
* Q' h( Z7 c/ F; Z% x9 v& {& D
& {* [! {0 Y9 w" X( p
while ~feof(fidin) % 判断是否为文件末尾
+ _$ s( J4 L% u; N9 J% w4 m, w
tline=fgetl(fidin); % 从文件读入一行文本(不含回车键)
" V- x5 U# f- _8 [
if ~isempty(tline) % 判断是否空行
! f) [4 M9 @. i- Y/ r
[m,n]=size(tline);
# d2 V" R% p0 F- c" ]) m* e
flag=1;
R! f' f: b* z5 _
for i=1:n %判断一行中有没有字符(+-.Ee和空格键除外)
5 v. G, f5 i2 Y& {" }6 Y# r u2 ?3 h
if ~(tline(i)==' '|tline(i)=='-'|tline(i)=='.'|tline(i)=='E'...
7 f) a/ x4 d r9 n. |
|tline(i)=='e'|tline(i)=='+'...
; o0 M0 [* Q0 F% [
|(double(tline(i))>=48&&double(tline(i))<=57))
( |. M( h, K+ Z0 Y' G5 [
flag=0;
5 A; R+ h! e) z% [- ~
break;
$ ]6 d: h' r9 B. c S
end
: f0 w1 J, S6 y2 s' }
end
3 ~! V% i6 Y) G
if flag==1 % 如果是数字行,把此行数据写入文件
; I- O' g3 T& {9 m' m! I+ A
fprintf(fidtmp,'%s\n',tline);
: _ l" H/ N' C7 N$ T. T
end
' K% _# U0 N( y- n
end
1 t- l' g/ J" j$ y8 T9 c$ w
end
* u6 F9 J2 m3 v/ X; h
% Y8 \$ v% g* j. ~' k. H5 T. B% i
fclose(fidin);
# p! ^) G+ B- D! y5 c: d
# R- G8 G6 U2 C3 A6 k8 n( b
fclose(fidtmp);
, A' n+ @" A$ Z ^) p
8 k: q2 A* a5 W- ?8 v" A1 K% f% x
data=textread(tmpfile);
; K8 Q1 V$ E! T) X
! _* s0 X5 E6 v
delete(tmpfile);
) Y6 H& z- [2 U+ ?7 f- G# r" I' x
U5 I0 j' a# l2 Q: b @- F( b
$ O7 T( _) ?0 i4 Q$ V2 W6 O
6 P3 Q6 E/ Y$ j; ^2 ?
---------------------------------------------------------------------------------------------------------
' z6 _; n$ K7 O
另外,如果要求不高,也可以使用 textread 函数跳过注释部分进行读取,不过前提是需要事先知道文件内容的结构(即哪行是数据、哪行是注释)
/ P' b* B7 {1 h# v& D
( N7 `! i+ e7 j6 t) ^
6.各列数据的分离:
5 H, Y' Q5 N! \& }' p# v: _/ g D
源文件:
. a9 I7 d3 W% O v
$ s/ V6 {! g7 K* k) W8 B, m
* D: h) V/ P2 y+ ]% j8 C5 V
CODE:
! k% v y6 H9 ~- p1 M
0 + 47038.7 1.05 09:26:07 C
3 j4 ?, L: h% ~& |" e$ d
2 + 46477.7 1.03 09:28:38 C
" E* g0 v9 Y3 t/ T4 k& Y( ^5 {3 w
4 + 44865.7 1.04 09:28:48 C
) ]) z. W+ d- z; o9 f
6 + 41786.4 1.03 09:28:56 C
, s1 ^" s1 e: k) K( J) b. T
8 + 39896.0 0.97 09:29:03 C
+ G5 B6 R$ N5 l' U+ e
10 + 37518.4 0.93 09:29:15 C
. Z" V7 V# l) A; R" S
12 + 35858.5 0.92 09:29:30 C
* e. _' J1 Y, K2 ?5 y. n1 Q
14 + 46105.0 1.03 09:30:21 C
$ ~+ V8 A7 S* ]7 v6 k2 Q
16 + 46168.6 6.89 09:30:30 C
% E, ~+ V# ?3 E5 \9 z
18 + 48672.3 4.33 09:30:40 C
4 t" _* i) S U
20 + 49565.7 0.49 09:30:48 C
- e" g* M8 T0 g( w$ |
22 + 49580.7 0.53 09:30:55 C
0 B. _$ S# H( n" A+ w
24 + 49602.3 0.84 09:31:03 C
, `3 Q$ Y5 z0 h; f
26 + 49582.5 1.51 09:31:11 C
$ W1 o, M3 C/ M+ G6 ^" l
28 + 49577.0 1.39 09:31:19 C
5 K/ i- b/ T. \% s& U* U
30 + 49589.3 0.61 09:31:27 C
- J2 U9 P3 ?- Y2 v
32 + 49578.3 1.06 09:31:29 C
+ K" d) u7 R6 h) z
34 + 49512.5 1.77 09:31:38 C
% r; T3 I6 C; S3 R$ z: [8 x
9 D' c6 j$ Z6 d% Z# U. Q6 }
5 Y. Y' H0 _% ~
! ]2 ]- R K! U$ B- z0 \+ O
# R/ A, [2 n: _5 n
解答:直接用 [a,b,c,d,e,f]=textread(yourfilename,'%d %c %f %f %s %c'); 便可
T: H6 Z( Q* K0 V
0 D( a9 L2 I1 h# d- d
5 o! J" L* O* D8 ?: E
三. 注意事项:
: Y+ G- q3 _+ z- K
7 N5 ~9 }! q) \+ X% G: ]# V
c4 H2 m" S5 y2 k( N+ N
1. 请在 matlab 中保持当前路径在该数据文件对应的目录下进行存取,否则,存取时请给出该数据文件的具体路径。
8 ]! t0 {" N! J) s
3 j: a& } y5 W2 [) o
2. 存取时,请给出该数据文件的全称(包括后缀名,读取mat文件时可省略)
' h' t3 G2 t5 C. w
6 N7 r( F" H( g; C
3. load data.txt和A=load(‘data.txt’)的区别请参阅精华贴:
. t! V$ G# X& l) X
6 d: w$ ^2 k# R4 b$ j) U! V- [& z
4. 请根据读写需要来打开文件,即根据你的需要来指定 fopen 的 permission 属性为读或写。如果只用 a 进行写入,就不能用 fread 读取。此时应该写完关闭文件,然后用 r 打开读取,或者直接用 a+ 进行同时读写操作。否则,会产生莫名其妙的问题!以下代码是一个错误的例子:
8 w8 x! [; `! Z/ N
. V) e6 S' A0 I9 q; c6 H! W6 G
5 _* m# ]: R( R; V
CODE:
) L6 e% H7 b. u; H7 y$ Z
8 [/ U' ^- J# E. C5 }2 N, h
filename='e.dat';
1 y2 E' ]! N0 {# D1 _3 L7 O' w
fid=fopen(filename,'a');
7 G. T0 I5 \" h- W) r) E
if fid<0
3 j& z3 z9 I9 t* @
error('fopen error');
* o0 X# ?. o, t
end
- Q4 A5 }& V& S- f' Z
s=[1 2 3 4;5 6 7 8];
2 O# Z- S# \4 h# q) t; g
fwrite(fid,s,'float32')
4 Z* @4 k5 f0 G9 o
[dd ll]=fread(fid,inf,'float32');%把t中的数据全部读出,即s矩阵。
) r3 k! [+ ^8 z6 s
fclose(fid);
& |, Z: U W. g+ g6 M9 B
) y8 I4 h# H) {
7 y4 K8 W2 \* o1 { v( p7 y
. v8 l8 o! v* d6 H8 r; m
* [; _4 ~8 B0 ]. B
, a- N& \2 a8 _3 d" |& `$ v
此时得到的dd, ll 是错误且无意义的!
( |, s1 b7 e! p* G$ Q( f( i0 t
$ F- ?1 _% i$ }
四. 其他相关问题:
7 X& \# h' n/ e) O5 P! }
k# @% h3 l5 P3 H6 o# \% f; J
1. 连续读取多个文件的数据,并存放在一个矩阵中:
8 g, D4 o! R0 l/ k$ {% ?& G
(1) 首先是如何读取文件名:
& D1 O! H) a' l( y: \
方法一:
" ^: ?6 A" D7 h& L- u$ @" F
filename=dir(‘*.jpg’);
, l3 C2 ~( v& E' v" W+ b* f# N
那么第i个文件的文件名就可以表示为
, \* }2 \: n+ d8 l1 F" l/ u
filename(i).name
. B& n% n( f" F+ ?; x6 {* T
文件数量为:length(filename)
" X( y+ b# \8 q; s
5 I7 T* H2 [; ~: G
方法二:
8 t! O8 o- L* X* y4 v; `
先在Windows的 MSDOS(命令行)中使用以下命令生成一个list.txt文件:
8 j6 `9 F* y& j! J3 V4 F
7 R. {. m; L+ [! M0 e
' U$ @' Y, j, W& L8 R
dir path\folder /on /b /s > path\list.txt
3 F. r' u6 e! i. h, V7 d' v& z
/ f% H! S# x: ]0 z
举例:dir d:\test /on /b /s > d:\list.txt
7 h0 ^5 L7 `8 ?3 h; h
; W' L q2 h" ~
然后在 matlab 中使用:
# q8 ]9 h4 i V2 u* N& n; s
& N6 n' u4 T9 [3 g& m5 O* q& }
filename = textread(sFileFullName,'%s');
1 O+ e' z. S2 b2 A
/ {4 {/ m3 x$ d; A) V- ^- j
把所有文件名读取到list细胞矩阵中,最后对filename{i}便可得到各文件名。
+ |; ?- L& q# P. c
% Y% t$ m/ y, J, E
(2) 然后是读取文件名的数据并存储:
% Z; ^# F2 I3 M& ]/ T/ I; b
假设每个文件对应的数据是m*n的,则:
% g" m7 F# c! V, Y) e4 I& C1 ]" U' v
( n. v- W# ^/ {, ~ L
CODE:
2 p0 ~" v0 x; C5 k8 i
k = length(filename);
2 W5 y. k* c" P( ^8 ]
) C5 m! v" ^) s) A8 l8 |( A0 ~
Data = zeros(m,n,k);
8 C$ ?1 I5 q$ L/ U9 l" U- d8 ?
( i3 n0 G, U0 ?$ _ f- r
for ii = 1:k
" E# a) {+ b( p6 a1 V4 L5 K2 g9 p
Data(:,:,ii) = yourreadstyle(filename{ii}); %yourreadstyle是对应的文件读取方式的函数
5 h) d: X3 v& L" o
end
8 m9 X% `7 W, `6 m6 C! ?5 i
; H; r# \4 f: ]; o5 D: D
3 S a9 S, N3 Y
+ R; J& Z, {" E; x0 R4 H
7 E' I: Y8 j7 O( L7 I& M
2. 连续读取多个文件的数据,并存放在多个矩阵(以文件名命名)中:
0 V/ C! [7 B0 N6 U8 p) }
假设每个文件对应的数据是m*n的,则以上述第二种文件名读取方法为例:
) W9 ]; m5 }- ^/ p9 A) `# H+ p
/ ^, @0 K) e$ ?9 w& P) l7 |
CODE:
) J6 d2 ^9 j0 |% Z% D
k = length(filename);
! h# J. [; g5 @7 e. _6 e+ d& z
for ii = 1:k
& Z. n4 I! m& J5 A- y
D = yourreadstyle(filename{ii});
2 e5 H, J: d" O' z" W0 ^( m8 S
eval([‘Data_’, num2str(ii), ‘ = D;’]);
2 G9 U3 [, | I% p1 r( u
end
* W- j, |3 v2 \+ d
- f, e5 e- [, V1 N
' {" |1 c& Y- y/ f
2 O1 I; d4 S$ }2 z, S1 u7 p
3. 文件名命名问题:
! ]- C& ~7 p- [& c1 A, k
文件名为 abc00001,abc00002,... abc00009,abc00010,... abc00099,abc00100,...abc00879. 准备把这些文件名给放到一个数组里面去。
4 [+ g4 x6 ~. Y) C6 q
0 H' q3 V) V% n& A. N" J
解答:
5 V$ h3 I' I) c2 G: V2 F
* v; ^) w$ T; X6 a( t$ l2 a, D5 h1 [
CODE:
- E: V% [# b( h/ \" q
a=cell(879,1);
H; |" @ O3 }% K k
for k=1:879
1 y1 _' v( E7 n' U4 J
a{k} = sprintf('%.5d',k);
* _3 a% I+ V0 @4 k' s$ ]7 g* a3 @7 \
end
; H4 [3 }0 k; Q( P% u: n' L
4 X2 T- I; Q2 u" [' l
: E% f+ b; B. ^. W& Z. N2 n5 P* x
4. 上述各种文件格式、类型自动识别问题:可以利用正则表达式来处理,使之通用性较强。例如使用以下代码可以自动处理上面提到了例1到例5各种情形,不过由于存在自动判断,对某些例子(如例1)效率自然要低一点,而对于另外的例子(如例3、例5)效率估计要高一点(少用了一个循环)。
6 @3 B! Z" ]! M+ z
8 s* h# o1 y5 c4 {. {4 _6 \
: W$ o& l7 W6 m) U' g8 ~
CODE:
, }0 H0 p' Q" ?7 I5 r
3 a% S; j) ^& ]6 l' _
function [data]=distilldata_eight(infile)
1 ]4 P B0 P- k* ]& i2 F L* H
%功能说明:
) x# N9 n" `! ?- w
%将保存数据的原始文件中的数值数据读入到一个data变量中(自动判断数据行)
, `- ?( _) r2 [7 |# y+ b
%使用说明:
/ U& s( Y' s0 U# b$ A. Q$ M3 N
% infile——原始数据文件名;
' Z+ |$ j- o( j6 p
% data=数据变量
0 p+ Y* ~# o0 _8 R J9 O+ Y
, p$ B; @6 ]9 t0 `6 b N
tmpfile='tmp2.mat';
# Q, O9 D; ?+ C; i: S3 h) d0 o3 f
% Q0 u Q5 S2 ?. u
fidin=fopen(infile,'r'); % 打开原始数据文件(.list)
" l" M) H! z! F7 S' l
$ q8 M9 I4 ~; \2 w3 v: S+ w
fidtmp=fopen(tmpfile,'w'); % 创建保存数据文件(不含说明文字)
- A% j: o3 Q) o2 e [8 F7 M$ `
, f0 I4 U, z0 ?% d# m( T- H& l
while ~feof(fidin) % 判断是否为文件末尾
! g6 M- n* e* X: u# O
tline=fgetl(fidin); % 从文件读入一行文本(不含回车键)
: s# @% v5 Z" B& T9 e
if ~isempty(tline) % 判断是否空行
8 L* _: f2 C1 y% z1 R5 P; u
str = '[^0-9 | \. | \- | \s | e | E]'; %正则表达式为:该行中是否包含除 - . E e 数字 和 空白字符 外的其他字符
- |0 \/ Q8 y8 V8 Q2 M1 Y7 y
start = regexp(tline,str, 'once');
: h/ B7 G$ e* }5 W
if isempty(start)
* f7 v2 E6 [3 k2 z
fprintf(fidtmp,'%s\n',tline);
8 d3 t! @* O, b* i) O, ^
end
) V) e! @: }1 k
end
# u w2 P' M2 f+ i/ ^
end
" U% E% A9 j" q( A _9 X; e3 D
! n1 P- F J; t K: H ~
fclose(fidin);
4 ~9 D* V( c8 N6 I& h: ~' q
! b% l7 H3 b9 T( T+ G/ E x
fclose(fidtmp);
+ q% p! R4 f5 I6 P( D/ ^
, l! K4 u( A& e- t
data=textread(tmpfile);
% H: z; [! {' y4 e% g. ]2 D
$ Y" t& j0 c0 R. P9 u+ t1 j" m l& P
delete(tmpfile)
2 t* m! d; @- A! d+ G
$ u2 f- k6 M' r, O1 F0 ?' C
; w0 Z4 @5 _4 U6 U
' G+ Z% Q8 l7 K# v# i
5. 大量数据的读取问题:
. u' ?+ e4 f. H8 `5 O3 Y+ v- t: w
可以考虑使用循环分批读取(特别是在各数据是独立的时候),或者使用稀疏矩阵来实现。另外,也可参考《深入浅出MATLAB 7_X混合编程》一书第一章
$ s+ z/ d+ Z( u- a) O
5 H! Q/ U1 V0 W( G
6. 读取整个txt文件的内容(获得文件中的所有字符):
% q$ _2 ?! n- W$ [4 R. A' z
- D3 L7 V5 G7 o! ^. t. q
CODE:
* ~3 E1 w( \5 I! a# C8 K5 m
9 q5 c1 r% L8 \' A8 n. t, n8 k
f = fopen('yourfilename.txt','rt'); % t 属性根据需要可省略
\+ p* `8 B; e T" j; b+ i
x = fread(f,'*char');
& z' F; X5 C0 D' C% U
fclose(f);
2 Z# O/ X8 `* E5 W
; o# U/ Z( c1 S6 T5 v+ m, E
2 l& @/ {3 |% V3 l1 t7 }
7. 把维数不同的矩阵及其变量名保存到一个 txt 文件中,例如 a1 = 123; a2 = [1 2 3;4 5 6] ,希望得到的 txt 文件如下:
! q; _/ i) T7 `- B9 A
/ L) ^$ q0 h2 T4 s& Y4 r. `. e$ e
3 f# M% U1 p& _
QUOTE:
6 R+ a8 o9 C6 p9 ~- f2 b- I
$ p' B C9 P/ \" h4 i# r. R+ R
a1:
0 v. W- L5 j! u) U) I+ R. M
123
9 C! y& Z6 {' T4 d! g o" i1 p
a2:
" x0 }9 B1 K6 |
1 2 3
3 s0 |- `/ N6 w
4 5 6
6 [. J' ?& a5 S- s3 b9 O
( a, w1 U$ S" r( a: B* a
* m& v# w' `2 a! P' h2 \: N2 t9 O! o
: R" l+ `7 D7 \; C4 D8 g
4 a% m' F: ?4 o. R
% x* ]9 O' _5 }2 J: @9 ?' m1 d
如果写入的时候简单一点,则可以采用以下方式,不过读取的时候比较麻烦:
3 S- _, M: I! [* H0 \" Z2 z% @5 L6 o
2 z$ O4 l/ @. U8 d7 J7 f
CODE:
8 S0 `/ Y; _' f" d
! ? t2 K/ e. b# Y7 P H
a1=123;
9 @2 d' n5 }7 W2 \% u1 w6 I/ s
a2=[1 2 3;4 5 6];
) |. Z& M' s7 m( n3 k
fid = fopen('myfile.txt', 'wt');
6 X$ m8 f7 M( x: b# M6 i1 S$ Z
for i=1:2
* q, K1 V. C7 L. e0 y
fprintf(fid, '%s: \n %s\n', ['a',int2str(i)], mat2str(eval(['a',int2str(i)])));
1 [, t* `7 Q7 S( k& m% `
end
- C. B( h- H! g2 B q5 f; ^1 n# z
fclose(fid);
9 C0 p. G$ a- M" O$ b0 _5 x/ l
4 w3 N6 [" L2 x. _& e. C8 p) P/ w
0 o# a# `: [+ |( C) `0 N2 D- I
相反,如果写入的时候复杂一点,则读取的时候会简单一点:
_9 F, j8 i/ {$ s- o( \/ A
: B# h. }7 O3 L( S4 }8 p4 a
CODE:
B/ q' q: p* d8 d1 p5 k# F
' [( E0 D& @% u4 S
a1=123;
! u+ I* P+ x \4 w2 ]
a2=[1 2 3;4 5 6];
9 W& b* P7 l0 P
fid = fopen('myfile.txt', 'wt');
- u3 ?4 d( o7 y/ p
for i=1:2
% l: F' v! V8 \' u
fprintf(fid, '%s: \n', ['a',int2str(i)]);
: v0 x! V! F( v! {' ?/ @
b = eval(['a',int2str(i)]);
" Y8 R/ q. u" M; L
fprintf(fid, [repmat('%d ', 1, size(b,2)), '\n'], b');
7 J2 V- }, y0 N
end
# j+ k, L( \" |
fclose(fid);
作者:
CCxiaom
时间:
2020-11-24 17:38
文档读取技巧教程
欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/)
Powered by Discuz! X3.2