几行代码求解释

我打开的这个abc.txt文本文件,有一些汉字,其他都是数字和英文字母!
Private Sub Command1_Click()
Open "d:\abc.txt" For Input As #1
Print Input(lof(1), 1)'顺序打开为什么会提示"超出文件尾"
Close
Print "------------"
Open "d:\abc.txt" For Binary As #1
Print Input(lof(1), 1)'同一个文件用二进制打开就没有问题,求解释
Close
End Sub
对教材上的打开文件这章内容非常不解,求高手:
求解,顺序打开文件、random 、binary 这3中打开文件方式『根本』上的区别,比如,什么样的文件是顺序文件,什么样的是二进制文件,越详细越好,有追分,谢谢!!
不会的就不要回复了,谢谢!!

没有几行字符,不会超过32k,仍然有问题!

binary 用line input #1,x 读取一行,遇到汉字开头的行就显示乱码啊!!

早期的VB是采用单字节处理方式(通常也称为ANSI方式),也就说一个英文字母用一个字节表示,一个汉字算两个字节,当然这样就可能出现半个汉字的问题。从VB 4.0起,VB采用了一种新的处理方式,即内部采用Unicode方式,即不论英文字母还是汉字,一律用两个字节表示,但Unicode还不够普及,所以VB只是在其内部完全使用Unicode,而在外部仍转换为人们习惯的ANSI方式,但在字符串处理上与先前的版本有所不同。例如:Len("电子&电脑")=5(这里的&号为半角字符),而在以前的版本或纯英文Windows中Len("电子&电脑")=9。除了Len、Left、Right等字符串函数受此影响外,Input函数也受此影响。Input函数的第一个参数是要读入的字符数,它采用的是和Len一样的计数方式,即一个英文字母算一个字符,而一个汉字(两个字节)算一个字符。这看起来是个好主意,你不会读入半个汉字,但实际上糟透了,因为VB的LOF函数和FileLen函数都返回的是字节数,VB中没有一个能区分汉字和英文字母的LOF函数或FileLen函数!如果你的文件中有100个汉字,那么LOF函数和FileLen函数返回文件长度200个字符,执行Input(200, filenum1),VB读到第100个汉字时就把文件读完了,所以提示错误:"输出超出文件尾"。而二进制就不同了,在二进制中,以字节为单位,一个汉字占两个字节,所以不会出现错误
VB读写文件要用到以下语句:
1、Open语句打开文件。
2、AS INPUT,OUTPUT,APPEND(文本方式),binary,random(二进制方式)打开文件
3、读文件使用Line Input、Input #,(以上为文本方式)和Get(以上为二进制方式)。
4、写文件使用Print #、Write(以上为文本方式)和Put(以上为二进制方式)。
5、Close语句关闭文件
5、二进制方式下移动文件位置使用Seek语句。

其中,你说的顺序打开文件INPUT是指文本方式打开,打开ANSI编码的文件正常,我试过打开UNICODE编码文件,用INPUT #读出来以后是乱码,需要用STRCONV来转换成ANSI才能显示!上面说了,此时内部采用Unicode方式,Len("中中中中")=4,
BINARY和RANDOM这两种打开方式几乎相同,不一样的是BINARY是以一个字节为单位,而RANDOM是以指定的长度为单位.这两种方式都是以二进制方式打开文件的,我曾经试过,用这两种方式打开一个文本文件时,得到的是二进制数据,如果是用INPUT 或 LINE INPUT 读入的话,假设s读入了"中中中中",用LEN(s)=7 (其实按道理来说应该是8,实际上用GET读取的也是8,但这里却是7,我问了一个朋友,他说可能是因为UNICODE存放高低位顺序的原因).拿"中中中中"来说吧,不同读入方法得到的二进制结果如下:
ANSI格式,内容"中中中中",打开方式:INPUT, 读取方式,INPUT #,结果:D6 D0 D6 D0 D6 D0 D6 D0 0D 0A
ANSI格式,内容"中中中中",打开方式:BINARY,读取方式,INPUT#,结果:D0 D6 D0 D6 D0 D6 3F 0A
D0 D6位置改变,导致出现乱码
其实顺序打开文件、random 、binary 这3中打开文件方式准确的说应该是两种,文本和二进制,其实文本文件和二进制文件的区别是什么,我想每个学电脑的人大概都明白吧,文本文件也是二进制文件的一种,文本文件也可以用二进制方式打开,只不过需要经过复杂的转换才能变成我们看到的ANSI字符,这样的话,文本方式打开文件,直接读取就可以得到我们看得懂的文字,当然更方便,但有些时候,比如处理图像声音等文件时,我们需要的是另一种效果,那样的话,文本方式就不太合适了,因为文本方式只认识标准ANSI或Unicode,其它的可能会忽略或去掉,所以,这个时候就是二进制上场的时候了!

以上仅为个人理解,不足之处还请见谅
温馨提示:答案为网友推荐,仅供参考
第1个回答  2008-09-08
看楼上的说了那么多,也有一些能解决问题的,不过我认为没有找到问题的本质。

我认为这个问题的原因在于:
Lof函数取得的文件长度为 英文字符个数+2*中文字符个数

而在读取是,一个中文字符是当作长度1来读取的,这样,读取的实际长度就应该等于 lof函数取得的文件长度-中文字符个数。 当文件中有中文字符时,这个长度明显的比lof函数取得的文件长度要小,当然会出现超出文件尾的提示啊。

我们可以做一个测试,假设
“d:\abc.txt”文件的内容为一个汉字加2个英文字符:"我wo"(不包括引号)
则 MsgBox LOF(1) 得出4
而用 Print Input(LOF(1) - 1, 1)确能输出"我wo",这个充分前面的推理是正确的。

至于解决办法,请参考<ouaizhanzhan - 助理 二级>,虽然简单,但我也不能把人家做好的直接copy过来吧,

最后祝你早日解决问题!!
第2个回答  2008-09-08
先说 input(),他的语法:Input(number, [#]filenumber),它第一个参数number指的是一次读取的字符的个数,一个汉字也是一个字符。
再说:lof(),这个函数返回的是一个打开的文件的字节的长度,我们知道一个汉字=2个字节,这样就是说,当文档中有汉字时,lof()返回的文件长度,要大于文件中字符的个数,因此用input(lof(1),1)这句会超出文件尾!那为什么用同样的语句,以binary打开时没有问题呢?
我的理解是(不知道对不对):
以二进制打开文件时,无论是什么内容的文件,读入内存都是0 和 1 的组合,所以 lof()返回的“实际文件长度”=“文件的字符个数”,因此不会超出文件尾!我没受过计算机专业知识的教育,全是个人看法,不保证对,希望知道确切答案的朋友给出解释!
还有,显示乱码的原因,偶也不晓得,盼答案!

PS:
djrm_yb说:
“d:\abc.txt”文件的内容为一个汉字加2个英文字符:"我wo"(不包括引号)
则 MsgBox LOF(1) 得出4
而用 Print Input(LOF(1) - 1, 1)确能输出"我wo",这个充分前面的推理是正确的。
这样理解是正确的,如果非要用input()的形式读取文件,正确的用法应该是:input(lof(#1)-(汉字个数)/2,#1),但是对一个很大的文件,你不可能数数有多少汉字再用 lof(1)- ?这句!因此,fkeugeqh 的说法也是不可行的!

ouaizhanzhan 同志的解释,我更不敢苟同,for input 怎么会是想文件里写东西呢?应该是读取吧! close 后面不加文件号表示关闭全部,根本没有影响的。另外把:
Open "d:\abc.txt" For Input As #1
Print Input(lof(1), 1)'顺序打开为什么会提示"超出文件尾"
Close
解释为“打开方式不对,把Input改成append,意思是,一行一行追加”,说明这位同志没有看仔细楼主的代码,这里的print是把文件全部输出到窗体,是me.print 的简写,压根就不是写入文件时的 “print #文件号”或“write #文件号”!还有binary打开文件,汉字可以解析,我试过楼主的第二段代码,读取汉字没有问题,但是为什么 “binary 用line input #1,x 读取一行,遇到汉字开头的行就显示乱码啊!!” 我也很费解!!

个人看法,仅供参考!!
第3个回答  2008-09-08
按多年使用VB经验来说。顺序打开任何文件都可以。
顺序打开文件是指从文件开到到结尾取出到一个变量。(个人理解)
Random这个一般用得少。一般用于打开文本数据库。
binary可用于读取任意文件。但与顺序的区别是binary的文件结尾(也就是Lof()长度取的是总字节长度,并以二进制方式读取。应该与数组变量一起使用,而顺序读取是取文件内容的字符长度。)

Open "d:\abc.txt" For Input As #1
Print Input(lof(1), 1)'顺序打开为什么会提示"超出文件尾"
这段代码是错误的。LOF(1)这个判断文件结尾已经超出范围。正确的应该是。
Open "d:\abc.txt" For Input As #1
Print Input(lof(1)-1, 1)
这样就不会超出结尾。因为每个文本文件在读取时会有一个换行符或称为结尾符。所以文件长度LOF(1)应该再减1。
第4个回答  2008-09-09
Print Input(lof(1)-1, 1) 试试
lof(1)是指文件的长度,你从文件的最后读取,1个字节当然会出错,-1就不会了

你第二句用二进制方式读取,就算你文件不存在,也不会出错的
至于打开文件的方式,建议你装一个msdn,到里面查一下vb的open语句,里面有详细的说明
第5个回答  2008-09-08
文本文件里不是乱码的,用input;表示往文件里写东西,但是不会自动换行。
文本文件是二进制文件,用binary;
随机读取文本文件,用random;

一般情况下,都是用input打开。

楼主,你打开文件要记得关闭掉,关闭的时候记得加文件号。
比如"close #1".

下面对你的错误做一些解释:
1 Open "d:\abc.txt" For Input As #1
Print Input(lof(1), 1)'顺序打开为什么会提示"超出文件尾"
Close
原因:打开方式不对,把Input改成append,意思是,一行一行追加。

2 "print #1,Mytext" 记得加上文件号。

PS:往文本文件里写东西的时候一般用append方式打开,表示往记事本里从后面追加数据。

希望楼主成功!!!!

最后,介绍一下读/写文本文件:

读:
Open "d:\r.txt" For Input As #1
Do While Not EOF(1) '从第1行开始读取,只要文件没有到最后就循环。
Line Input #1, str '循环读取文本文件里的每一行数据到变量。
i = i + 1 ’这个变量可以记录文本有多少行。
Loop
Close #1
写:
Open "d:\w.txt" For append As #2 '从文本末尾开始追加数据
print #2,str
Close #1
----------------------------------------------------------------------
祝你成功!!!!

补充:binary读的是二进制的,汉字无法解析的。不建议这样的方式。