I/O中的一些问题的研究

本文探讨了使用Common Lisp处理文件流时,如何通过file-position获取当前文件指针的位置,以及在不同文件格式(如txt、doc)中处理换行符(10LF/13CR)的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

file-position 接受一个打开的流,然后返回文件的当前位置,也就是读取或者写入该流的元素的数量。

1:从io4.db中往io3.db中输入数据,并且显示读入和写入的元素的数量。下面是我考到wps中,输出显示格式,你发现他在第二个引号换行了,然后他后面也换行了。在后面换行的话,正常,因为在write-line的时候,他会给字符串加上一个换行符,然后我就测试了一下在wps的doc里面是不是碰见13 CR也同样会换行,也就是说现在wps中的doc里面碰见13CR/10LF中任何一个都会换行。

CL-USER>  (with-open-file (out "d:/emacs/io3.db"
			       :direction :output
			       :if-exists :supersede)
	   (with-open-file (in "d:/emacs/io4.db")
	     (loop for line = (read-line in nil)
		while line
		do(format t "in file-position : ~s~%" (file-position in))
		  (write-line line out)
		  (format t "out file-position : ~s~%" (file-position out))
		  (format t "~s~%" line))))
in file-position : 7
out file-position : 7
"nihao
"
in file-position : 13
out file-position : 13
"lili
"
in file-position : 15
out file-position : 16
"hi"
NIL
验证在wps中的doc里面碰见13CR/10LF中任何一个都会换行。

CL-USER> (with-open-file (out "d:/emacs/io.doc"
			       :direction :output
			       :if-exists :supersede
			       :element-type '(unsigned-byte 8))
	     (loop repeat 10
		do(write-byte (read *query-io* nil) out)
		  (format t "out file-position : ~s~%" (file-position out))))
97
out file-position : 1
13
out file-position : 2
98
out file-position : 3
10
out file-position : 4
99
out file-position : 5
100
out file-position : 6
13
out file-position : 7
101
out file-position : 8
10
out file-position : 9
101
out file-position : 10
NIL
最后在doc中显示形式如下,也就是当10/13时都换行了。
a
b
cd
e
e

验证在txt里面13CR/10LR的效果

CL-USER> (with-open-file (out "d:/emacs/io3.txt"
			       :direction :output
			       :if-exists :supersede
			       :element-type '(unsigned-byte 8))
	     (loop repeat 12
		do(write-byte (read *query-io* nil) out)
		  (format t "out file-position : ~s~%" (file-position out))))
97
out file-position : 1
10
out file-position : 2
98
out file-position : 3
13
out file-position : 4
99
out file-position : 5
13
out file-position : 6
10
out file-position : 7
100
out file-position : 8
10
out file-position : 9
13
out file-position : 10
101
out file-position : 11
102
out file-position : 12
NIL
在io3.txt里面的形式,但是如果你再把下面的结果再放到doc他又会是另一种形式,因为13/10仍旧是存在的,只是不显示出来,我又把io3.txt按二进制流读了出来。可以看到13/10都在,所以说在wps中会是另一种景象。


CL-USER>  (let ((in (open "d:/emacs/io3.txt" :element-type '(unsigned-byte 8))))  
	   (loop for c = (read-byte in nil)  
	      while c  
	      do(format t "~a" c))  
	   (close in))  
971098139913101001013101102
T
2:上面说的是wps中编码的情况,下面说一下为啥写了16个而却只读了15个字符?
因为当readline的时候,他会把newline去掉然后把剩下的封装成string作为值。(readline可以佐证因为只有13才会输出显示^M)。同时如果你把io3.db按照原样二进制流输出最后一个字符为10,也就是newline.因为write-line会给字符串加上一个newline,所以你才会发现前面收支是平衡的,直到读最后一行时,因为源文件的最后一行没有换行符,而在write-line的时候给他加了一个newline,所以也就多了一个。

我按二进制流输出刚才写入到的io3.db中的内容你发现却是多了一个10

CL-USER> (let ((in (open "d:/emacs/io3.db" :element-type '(unsigned-byte 8))))  
	   (loop for c = (read-byte in nil)  
	      while c  
	      do(format t "~a" c))  
	   (close in))  
110105104971111310108105108105131010410510
T
第二种佐证方式:既然read-line他会剔除newline10,那么我们就看一下read-line的结果是不是却是少了10.而我为啥用图片呢?因为我发现如果我粘代码跟结果的话,最后结果显示是图片下面的那个形式。也就是说本身csdn里面碰到13也是会换行的。图片中确实是多了一个^M,我上一篇已经说了^M是13.


"nihao
""lili
""hi"
NIL
3:其实我现在一直有个疑问,就是如果你直接复制repl中的代码粘贴到本地的txt,他格式不变。因为在txt里面换行是1310,为啥在repl时候他没有显示为^M形式呢?下面是我从cl-user后面剪切一段代码然后放到txt里面的输出形式输出结果
CL-USER> (let ((in (open "d:/emacs/test.txt" :element-type '(unsigned-byte 8))))  
	   (loop for c = (read-byte in nil)  
	      while c  
	      do(format t "~a" c))  
	   (close in))  
	
40108101116324040105325241411310932323240494141
源文件:
(let ((i 4))
   (1))

总结:with-open-file可以进行嵌套同时对多个流进行控制,只是注意他们的语法作用域。

            (read *query-io* nil)读取从键盘端输入的数据,(write-line *query-io*)输出显示到显示器上面

            wps/csdn/txt 他们碰到13/10字符时的效果不一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值