PHP Conference Japan 2024

ftell

(PHP 4, PHP 5, PHP 7, PHP 8)

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

描述

ftell(资源 $stream): 整数|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 个注释

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
burninleo at gmx dot net
15 年前
当通过 fopen('file','ab') 打开文件以进行追加时,文件指针应该位于文件末尾。但是即使文件不为空,甚至在向文件中写入一些文本之后,ftell() 也会返回 int(0)。
d9k at ya dot ru
2 年前
不得不使用

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

代替

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

在 Ubuntu 上从 php 7 升级到 8 后。
d9k at ya dot ru
2 年前
不得不使用

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

代替

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

在 Ubuntu 上从 php 7 升级到 8 后。
mbirth at webwriters dot de
19 年前
注意!如果您使用“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() 的工作效果符合预期 - 使用了正确的字节值。
mweierophinney at gmail dot com
19 年前
实际上,对于仅追加流,ftell() 给出的结果不仅仅是不确定的;它给出了从文件末尾开始的偏移量,该偏移量是在追加任何数据之前定义的。因此,如果您打开一个包含 3017 个字符的文件,并追加 41 个字符,然后执行 ftell(),则返回的值将为 41。
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";}

?>
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