ftell

(PHP 4、PHP 5、PHP 7、PHP 8)

ftell返回文件读/写指针的当前位置

描述

ftell(resource $stream): int|false

返回由 stream 引用的文件指针的位置。

参数

stream

文件指针必须有效,并且必须指向由 fopen()popen() 成功打开的文件。 ftell() 对只追加流(以 "a" 标记打开)给出未定义的结果。

返回值

返回由 stream 引用的文件指针的位置,表示为整数;即它在文件流中的偏移量。

如果发生错误,则返回 false

注意: 由于 PHP 的整数类型是有符号的,并且许多平台使用 32 位整数,因此对于大于 2GB 的文件,一些文件系统函数可能会返回意外的结果。

示例

示例 #1 ftell() 示例

<?php

// 打开文件并读取一些数据
$fp = fopen("/etc/passwd", "r");
$data = fgets($fp, 12);

// 我们在哪里?
echo ftell($fp); // 11

fclose($fp);

?>

参见

添加注释

用户贡献的注释 8 个注释

7
Mindaugas
9 年前
通过 fopen('file','a+') 打开文件进行读写时,文件指针应位于文件末尾。但是 ftell() 返回 int(0),即使文件不为空。似乎还有两个指针,第一个用于读取,第二个用于写入,因为它们在第一个操作(读取或写入)上表现不同。

示例
<?php
$file
= fopen('counter.txt', 'w');
fwrite($file, '123456789');
fclose($file);

$file = fopen('counter.txt', 'r');
echo
ftell($file) . ' "' . fgets($file) . '" ' . ftell($file) . PHP_EOL;
fclose($file);

$file = fopen('counter.txt', 'a+');
echo
ftell($file) . ' "' . fgets($file) . '" ' . ftell($file) . PHP_EOL;
fclose($file);

$file = fopen('counter.txt', 'r+');
fwrite($file, 'rr');
echo
ftell($file) . ' "' . fgets($file) . '" ' . ftell($file) . PHP_EOL;
fclose($file);

$file = fopen('counter.txt', 'a+');
fwrite($file, 'aa');
echo
ftell($file) . ' "' . fgets($file) . '" ' . ftell($file) . PHP_EOL;
fclose($file);

$file = fopen('counter.txt', 'r');
echo
ftell($file) . ' "' . fgets($file) . '" ' . ftell($file) . PHP_EOL;
fclose($file);
?>

结果
0 "123456789" 9
0 "123456789" 9
2 "3456789" 9
2 "" 2
0 "rr3456789aa" 11
2
burninleo at gmx dot net
14 年前
通过 fopen('file','ab') 打开文件进行追加时,文件指针应位于文件末尾。但是 ftell() 返回 int(0),即使文件不为空,即使在将一些文本写入文件之后也是如此。
0
d9k at ya dot ru
1 年前
不得不使用

<?php
posix_isatty
(STDIN) == false
?>

而不是

<?php
ftell
(STDIN) !== false
?>

在将 ubuntu 上的 php 从 7 升级到 8 之后。
0
d9k at ya dot ru
1 年前
不得不使用

<?php
posix_isatty
(STDIN) == false
?>

而不是

<?php
ftell
(STDIN) !== false
?>

在将 ubuntu 上的 php 从 7 升级到 8 之后。
0
mbirth at webwriters dot de
18 年前
注意!如果您使用 "text" 修饰符(例如 'rt')打开文件,并且文件包含 \r\n 作为行尾,ftell() 返回的位置就像只包含 \n 作为行尾一样。

示例
如果第一行只包含 1 个字符,后面跟着 \r\n,则第二行的开头应该是位置 3。(1 个字符 + \r + \n = 3 个字节)但是 ftell() 会返回 2 - 忽略一个字节。如果您在第 3 行调用 ftell(),该值将与实际值相差 2 个字节。错误随着每一行而增大。

(在 Windows 上的 PHP 5.0.4 中观察到这种行为。)

但是:fseek() 按预期工作 - 使用真实的字节值。
0
mweierophinney at gmail dot com
19 年前
实际上,对于仅追加流,ftell() 给出的结果不仅仅是不确定的;它给出的结果是追加任何数据之前定义的文件末尾的偏移量。因此,如果您打开一个有 3017 个字符的文件,追加 41 个字符,然后执行 ftell(),则返回的值将是 41。
-2
php at michielvleugel dot com
19 年前
在尝试确定是否将某些内容管道传输到命令行脚本时,执行 fgets(STDIN) 并不明智,因为它在没有管道传输任何内容时会无限期地等待。相反,我发现 STDIN 上的 ftell 非常有用:如果管道传输了某些内容,它将返回一个整数值 0,如果没有管道传输任何内容,则什么也不返回。

#!/usr/bin/php4 -q
<?
# 以下内容如果没有任何管道传输将挂起
#$sometext = fgets(STDIN, 256)

$tell = ftell(STDIN);

if (is_integer($tell)==true)
{echo "有一些内容被管道传输: ".fread(STDIN,256)."\n";}
else
{echo "没有任何内容被管道传输\n";}

?>
-3
missilesilo at gmail dot com
17 年前
回复 php at michielvleugel dot com

在 PHP 5.2.0 和 FreeBSD 5.4 上似乎并非如此。

#!/usr/local/bin/php
<?php
$tell
= ftell(STDIN);
var_dump($tell);
?>

root@localhost:/home/david# echo Hello World | ./test.php
int(0)
root@localhost:/home/david# ./test.php
int(6629927)

当一些内容被管道传输到脚本时,它会返回一个整数值 0,但是,当没有任何内容被管道传输到脚本时,它也会返回一个整数。

代码应该修改为以下内容

#!/usr/local/bin/php
<?php
$tell
= ftell(STDIN);

if (
$tell === 0)
echo
"有一些内容被管道传输: " . fread(STDIN,256) . "\n";
else
echo
"没有任何内容被管道传输\n";
?>

结果是

root@localhost:/home/david# echo Hello World | ./test.php
有一些内容被管道传输: Hello World
root@localhost:/home/david# ./test.php
没有任何内容被管道传输
To Top