Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在大文件的最后一个字符之前插入字符串_Php_Fseek - Fatal编程技术网

Php 如何在大文件的最后一个字符之前插入字符串

Php 如何在大文件的最后一个字符之前插入字符串,php,fseek,Php,Fseek,我有一个由单个字符串组成的非常大的文件。由于文件的大小,我不想将整个字符串读入内存 最后一个字符将始终是右括号],因为此字符串是json数组。我想在右括号前插入一个小json对象(表示为字符串)。我已经看到了一些想法,但无法让任何东西发挥作用 如您所见,我正在尝试打开文件,并使用fseek将文件指针移动到]前面。然后我尝试将新字符串写入该位置的现有字符串中 但是,这样做的效果只是将新字符串附加到现有字符串的末尾,这不是我想要的 作为一个简化的示例,假设文件开始时包含以下字符串: [{“name”

我有一个由单个字符串组成的非常大的文件。由于文件的大小,我不想将整个字符串读入内存

最后一个字符将始终是右括号
]
,因为此字符串是json数组。我想在右括号前插入一个小json对象(表示为字符串)。我已经看到了一些想法,但无法让任何东西发挥作用

如您所见,我正在尝试打开文件,并使用
fseek
将文件指针移动到
]
前面。然后我尝试将新字符串写入该位置的现有字符串中

但是,这样做的效果只是将新字符串附加到现有字符串的末尾,这不是我想要的

作为一个简化的示例,假设文件开始时包含以下字符串:

[{“name”:“alice”,“city”:“london”}]

然后,我想使用以下代码将第二个人添加到此列表:

$new_person = ",{\"name\":\"bob\",\"city\":\"paris\"}";

$filename = "people.json";
$fh = fopen($filename, "a+");
$filesize = filesize($filename);
$stat = fstat($fh);
fseek($fh, $stat[$filesize]-1);
fwrite($fh, $new_person);
fclose($fh); 
但我得到的是一个包含以下字符串的文件:

[{“name”:“alice”,“city”:“london”}],{“name”:“bob”,“city”:“paris”}

我的PHP技能很差。我无法判断我的
fseek
是否指向了错误的位置,或者问题是否在其他地方。感谢您的帮助。

来自(我的重点):

a+
:打开进行读写;将文件指针放在文件末尾。如果文件不存在,请尝试创建它在此模式下,fseek()仅影响读取位置,写入操作始终附加。

改用
r+
模式,而不是
fstat
您可以执行以下操作:

fseek($fh, -1, SEEK_END);
从(我的)重点:

a+
:打开进行读写;将文件指针放在文件末尾。如果文件不存在,请尝试创建它在此模式下,fseek()仅影响读取位置,写入操作始终附加。

改用
r+
模式,而不是
fstat
您可以执行以下操作:

fseek($fh, -1, SEEK_END);

请尝试以下代码来获得您的解决方案,我已经测试过,它的工作很好

try{
    $new_person = ",{\"name\":\"bob\",\"city\":\"paris\"}]";
    $filename = "people.json";
    $fh = fopen($filename, "a+");
    $stat = fstat($fh);
    ftruncate($fh, $stat['size'] - 2);
    fwrite($fh, $new_person);
    fclose($fh); 
}catch(Exception $exc){
    echo($exc->getMessage());
}

请尝试以下代码来获得您的解决方案,我已经测试过,它的工作很好

try{
    $new_person = ",{\"name\":\"bob\",\"city\":\"paris\"}]";
    $filename = "people.json";
    $fh = fopen($filename, "a+");
    $stat = fstat($fh);
    ftruncate($fh, $stat['size'] - 2);
    fwrite($fh, $new_person);
    fclose($fh); 
}catch(Exception $exc){
    echo($exc->getMessage());
}

fopen也这样做。所有文件内容都将加载到MemoryTank。我怀疑这可能与此有关,但误读了文档。@NiettheDarkAbsol无论如何指针必须到达最后一行才能附加数据。事实上,@AnantSingh--AlivetoDie您提出了一个有趣的问题。我真的没有任何理由需要在文件末尾追加。我可以把这个对象添加到数组的开头。@AnantSingh--AlivetoDie,是吗?这并不涉及将文件读入内存,只涉及移动指针。绝对最坏情况追加会导致文件超出其当前文件分配块,并被推入新的文件分配块。即便如此,fopen也会这么做。所有文件内容都将加载到MemoryTank。我怀疑这可能与此有关,但误读了文档。@NiettheDarkAbsol无论如何指针必须到达最后一行才能附加数据。事实上,@AnantSingh--AlivetoDie您提出了一个有趣的问题。我真的没有任何理由需要在文件末尾追加。我可以把这个对象添加到数组的开头。@AnantSingh--AlivetoDie,是吗?这并不涉及将文件读入内存,只涉及移动指针。绝对最坏情况追加会导致文件超出其当前文件分配块,并被推入新的文件分配块。即使这样,也没什么大不了的。