浏览 2709 次
锁定老帖子 主题:file:read_file的注意细节
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-03-05
4> file:read_file("/proc/cpuinfo"). {ok,<<>>} 11> {ok, IoDevice} = file:open("/proc/cpuinfo", [binary]),file:read(IoDevice, 1024). {ok,<<"processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 15\nmodel name\t: Intel(R) Core(TM)2 CPU "...>>} 同样的虚拟文件 不同的读法一个有内容 一个没有。 真实的文件就不存在这个问题。 erl -smp disable (禁止多smp的原因是容易找到pid) strace -p PID 结果如下: 。。。。 stat("/proc/cpuinfo", {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 open("/proc/cpuinfo", O_RDONLY) = 7 close(7) = 0 stat("/proc/cpuinfo", {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 open("/proc/cpuinfo", O_RDONLY) = 7 poll([{fd=3, events=POLLIN|POLLRDNORM}, {fd=5, events=POLLIN|POLLRDNORM}, {fd=0, events=POLLIN|POLLRDNORM}], 3, 0) = 0 clock_gettime(CLOCK_MONOTONIC, {457571, 853399847}) = 0 read(7, "processor\t: 0\nvendor_id\t: Genuin"..., 8192) = 1238 看下源码红色部分: static void invoke_read_file(void *data) { struct t_data *d = (struct t_data *) data; size_t read_size; int chop; if (! d->c.read_file.binp) { int fd; int size; if (! (d->result_ok = efile_openfile(&d->errInfo, d->c.read_file.name, EFILE_MODE_READ, &fd, &d->c.read_file.size))) { goto done; } d->fd = fd; size = (int) d->c.read_file.size; if (size != d->c.read_file.size || ! (d->c.read_file.binp = driver_alloc_binary(size))) { d->result_ok = 0; d->errInfo.posix_errno = ENOMEM; goto close; } d->c.read_file.offset = 0; } read_size = (size_t) (d->c.read_file.size - d->c.read_file.offset); if (! read_size) goto close; chop = d->again && read_size >= FILE_SEGMENT_READ*2; if (chop) read_size = FILE_SEGMENT_READ; d->result_ok = efile_read(&d->errInfo, EFILE_MODE_READ, (int) d->fd, d->c.read_file.binp->orig_bytes + d->c.read_file.offset, read_size, &read_size); if (d->result_ok) { d->c.read_file.offset += read_size; if (chop) return; /* again */ } close: efile_closefile((int) d->fd); done: d->again = 0; } static void invoke_read(void *data) { struct t_data *d = (struct t_data *) data; int status, segment; size_t size, read_size; segment = d->again && d->c.read.bin_size >= 2*FILE_SEGMENT_READ; if (segment) { size = FILE_SEGMENT_READ; } else { size = d->c.read.bin_size; } read_size = size; if (d->flags & EFILE_COMPRESSED) { read_size = erts_gzread((gzFile)d->fd, d->c.read.binp->orig_bytes + d->c.read.bin_offset, size); status = (read_size != -1); if (!status) { d->errInfo.posix_errno = EIO; } } else { status = efile_read(&d->errInfo, d->flags, (int) d->fd, d->c.read.binp->orig_bytes + d->c.read.bin_offset, size, &read_size); } if ( (d->result_ok = status)) { ASSERT(read_size <= size); d->c.read.bin_offset += read_size; if (read_size < size || !segment) { d->c.read.bin_size = 0; d->again = 0; } else { d->c.read.bin_size -= read_size; } } else { d->again = 0; } } 也就是说read_file 在发现文件长度为0的时候 不进行进一步读取.所以使用的时候请注意。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |