2
cat file_ro.py 
import sys
def file_open(filename):
        fo=open(filename,'r')
        fo.seek(7)
        read_data=fo.read(3)
        fo.close()
        print read_data
file_open("file.py")

但 strace 说

readlink("file_ro.py", 0x7fff31fc7ea0, 4096) = -1 EINVAL (Invalid argument)
getcwd("/home/laks/python", 4096)       = 18
lstat("/home/laks/python/file_ro.py", {st_mode=S_IFREG|0755, st_size=150, ...}) = 0
stat("file_ro.py", {st_mode=S_IFREG|0755, st_size=150, ...}) = 0
open("file_ro.py", O_RDONLY)            = 3
fstat(3, {st_mode=S_IFREG|0755, st_size=150, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa671a6c000
fstat(3, {st_mode=S_IFREG|0755, st_size=150, ...}) = 0
lseek(3, 0, SEEK_SET)                   = 0
read(3, "import sys\ndef file_open(filenam"..., 128) = 128
read(3, "ile_open(\"file.py\")\n\t\n", 4096) = 22
close(3)                                = 0
munmap(0x7fa671a6c000, 4096)            = 0
stat("file_ro.py", {st_mode=S_IFREG|0755, st_size=150, ...}) = 0
open("file_ro.py", O_RDONLY)            = 3
fstat(3, {st_mode=S_IFREG|0755, st_size=150, ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff31fc9e30) = -1 ENOTTY (Inappropriate ioctl for device)
fstat(3, {st_mode=S_IFREG|0755, st_size=150, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa671a6c000
lseek(3, 0, SEEK_CUR)                   = 0
read(3, "import sys\ndef file_open(filenam"..., 4096) = 150
lseek(3, 150, SEEK_SET)                 = 150
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0x7fa671a6c000, 4096)            = 0
open("file.py", O_RDONLY)               = 3
fstat(3, {st_mode=S_IFREG|0755, st_size=305, ...}) = 0
fstat(3, {st_mode=S_IFREG|0755, st_size=305, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa671a6c000
lseek(3, 0, SEEK_SET)                   = 0
read(3, "import ", 7)                   = 7
read(3, "sys\ndef file_open(filename):\n\t\"\""..., 4096) = 298
close(3)                                = 0
munmap(0x7fa671a6c000, 4096)            = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa671a6c000
write(1, "sys\n", 4sys
)                    = 4
rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x306140efa0}, {0x306d10b2b0, [], SA_RESTORER, 0x306140efa0}, 8) = 0
close(5)                                = 0
munmap(0x7fa671952000, 4096)            = 0
exit_group(0)  

正如你在上面看到的 -

读取(3,“导入系统\ndef file_open(文件名”...,4096)= 150

当程序说只读取 3 个字节时,为什么 read() 返回 150 个字节?

4

2 回答 2

6

由于您正在读取另一个 py 文件,因此事情变得混乱,但似乎内置函数忽略了您传递给 read() 的值,并缓冲了其余的值。也许尝试使用 os.read() 代替?

文件_ro.py:

import sys
def file_open(filename):
        fo=open(filename,'r')
        fo.seek(7)
        read_data=fo.read(3)
        fo.close()
        print read_data
file_open("zzz")

zz:

12345678901234567890123456789012345678901234567890

追踪:

...
open("zzz", O_RDONLY|O_LARGEFILE)       = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=51, ...}) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=51, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb73fb000
_llseek(3, 0, [0], SEEK_SET)            = 0
read(3, "1234567", 7)                   = 7
read(3, "89012345678901234567890123456789"..., 4096) = 44
close(3)                                = 0
...

您可以指定要打开的缓冲区的大小('zzz', buffering=0),或者我使用了 os 模块,并且可以根据需要更紧密地控制文件读取:

文件_ro2.py:

import sys, os
def file_open(filename):
        fo=os.open(filename, os.O_RDONLY)
        os.lseek(fo, 7, 0)
        read_data=os.read(fo, 3)
        os.close(fo)
        print read_data
file_open("zzz")

strace2:

...
open("zzz", O_RDONLY|O_LARGEFILE)       = 3
_llseek(3, 7, [7], SEEK_SET)            = 0
read(3, "890", 3)                       = 3
close(3)                                = 0
...
于 2010-07-09T11:40:58.107 回答
6

缓冲。为了避免这种情况,请使用open(filename, 'rb', bufsize=0)

于 2010-07-10T13:19:17.553 回答