本文件转自链接:http://www.bingx.com/html/lamp/2009/0914/159.html
If there is a file that´s excessively being rewritten by many different users, you´ll note that two almost-simultaneously accesses on that file could interfere with each other. For example if there´s a chat history containing only the last 25 chat lines. Now adding a line also means deleting the very first one. So while that whole writing is happening, another user might also add a line, reading the file, which, at this point, is incomplete, because it´s just being rewritten. The second user would then rewrite an incomplete file and add its line to it, meaning: you just got yourself some data loss!
If flock() was working at all, that might be the key to not let those interferences happen - but flock() mostly won´t work as expected (at least that´s my experience on any linux webserver I´ve tried), and writing own file-locking-functions comes with a lot of possible issues that would finally result in corrupted files. Even though it´s very unlikely, it´s not impossible and has happened to me already.
So I came up with another solution for the file-interference-problem:
1. A file that´s to be accessed will first be copied to a temp-file directory and its last filemtime() is being stored in a PHP-variable. The temp-file gets a random filename, ensuring no other process is able to interfere with this particular temp-file.
2. When the temp-file has been changed/rewritten/whatever, there´ll be a check whether the filemtime() of the original file has been changed since we copied it into our temp-directory.
2.1. If filemtime() is still the same, the temp-file will just be renamed/moved to the original filename, ensuring the original file is never in a temporary state - only the complete previous state or the complete new state.
2.2. But if filemtime() has been changed while our PHP-process wanted to change its file, the temp-file will just be deleted and our new PHP-fileclose-function will return a FALSE, enabling whatever called that function to do it again (ie. upto 5 times, until it returns TRUE).
These are the functions I´ve written for that purpose:
<?php
$dir_fileopen = "../AN/INTERNAL/DIRECTORY/fileopen";
function randomid() {
return time().substr(md5(microtime()), 0, rand(5, 12));
}
function cfopen($filename, $mode, $overwriteanyway = false) {
global $dir_fileopen;
clearstatcache();
do {
$id = md5(randomid(rand(), TRUE));
$tempfilename = $dir_fileopen."/".$id.md5($filename);
} while(file_exists($tempfilename));
if (file_exists($filename)) {
$newfile = false;
copy($filename, $tempfilename);
}else{
$newfile = true;
}
$fp = fopen($tempfilename, $mode);
return $fp ? array($fp, $filename, $id, @filemtime($filename), $newfile, $overwriteanyway) : false;
}
function cfwrite($fp,$string) { return fwrite($fp[0], $string); }
function cfclose($fp, $debug = "off") {
global $dir_fileopen;
$success = fclose($fp[0]);
clearstatcache();
$tempfilename = $dir_fileopen."/".$fp[2].md5($fp[1]);
if ((@filemtime($fp[1]) == $fp[3]) or ($fp[4]==true and !file_exists($fp[1])) or $fp[5]==true) {
rename($tempfilename, $fp[1]);
}else{
unlink($tempfilename);
if ($debug != "off") echo "While writing, another process accessed $fp[1]. To ensure file-integrity, your changes were rejected.";
$success = false;
}
return $success;
}
?>
$overwriteanyway, one of the parameters for cfopen(), means: If cfclose() is used and the original file has changed, this script won´t care and still overwrite the original file with the new temp file. Anyway there won´t be any writing-interference between two PHP processes, assuming there can be no absolute simultaneousness between two (or more) processes.
分享到:
相关推荐
标题中的“一个十分好用的hex文件编辑及diff工具”指的是该软件主要功能是用于编辑十六进制(hex)格式的文件以及进行差异比较(diff)。在计算机领域,hex编辑器是一种高级工具,允许用户查看和修改二进制文件的...
国外一款diff工具,简洁的英文界面。可比较两个文件夹的异同、两个文件的异同,适用于代码版本比较以及文件备份时的查缺补漏
wc、sort 和 diff 命令是 Linux 中三个非常有用的文件处理命令,本文将详细介绍这三个命令的使用方法和选项。 wc 命令 ------ wc 命令是 Linux 中一个非常有用的命令,用于统计文件中的字节数、字数、行数等信息。...
WinMerge是一款在Windows操作系统下广泛使用的文件差异对比工具,它能够帮助用户快速识别并解决两个文件或目录之间的差异。这款工具以其直观易用的界面、强大的对比功能以及丰富的自定义选项而深受程序员和文档管理...
首先,diff算法的基本思想是通过查找最长公共子序列(Longest Common Subsequence,LCS)来确定两个文本文件的差异。LCS是指在不改变序列原有顺序的情况下,两个序列中最大长度的相同子序列。通过找到LCS,diff可以...
diff算法的核心思想是基于动态规划,通过构建一个二维矩阵来记录两个文本文件中的对应行或字符之间的相似度。这个矩阵的每个元素代表了将前一个文件的一个子序列转换为后一个文件的相同长度子序列所需的最小操作数。...
Diff算法的核心思想是将两个文件分割成多个片段,然后比较这些片段的相似性。一种常见的实现方式是使用最长公共子序列(Longest Common Subsequence,LCS)方法。LCS寻找两个序列中的最长子序列,即使这个子序列在原...
`diff`命令是Unix/Linux操作系统中的一个核心工具,也广泛应用于Cygwin等Windows环境的类Unix工具集。它的主要功能是对比两个文件或目录之间的差异,并以可读的格式显示出来。在软件开发、系统管理和文档编辑等领域...
源码中会涉及到字符串处理、内存管理、文件操作和算法设计等多个方面。 `diff`的核心算法是Myers的“最小编辑距离”算法,它以高效的方式计算两个文本序列的最小改动次数。此外,`diff`还需要处理一些边界情况,如...
4. `diff.bpf`和`diff.bpr`:这些可能是某种中间格式的文件,用于存储`diff`算法处理过程中的数据,或者是在特定环境中优化`diff`性能的配置文件。 5. `diff.res`和`diff.tds`:这些可能是资源文件或编译器生成的...
2. **段落比较**:除了字符级别的比较,jsdiff还支持对整个段落进行比较,适合处理大型文本文件或多行代码。 3. **HTML高亮**:该库能够生成HTML格式的比较结果,用不同的颜色高亮显示差异部分,使得人眼阅读更直观...
`sebastianbergmann/diff`库就是这样一个专门用于进行差异比较的独立组件,它原本是PHPUnit测试框架的一部分,但现在已被提取出来,可以单独使用。这个组件提供了强大的功能,帮助开发者直观地看到两个数组、对象...
`diff_tool`是一款强大的文件对比工具,它可以帮助用户快速识别和理解两个或多个文件之间的差异。本文将详细介绍`diff_tool`的使用方法、功能以及其在实际工作中的应用。 首先,`diff_tool`的核心功能在于比较文件...
当两个或多个用户同时对同一份文件进行修改并试图提交时,SVN会检测到冲突并阻止其中一个用户的提交,以避免破坏文件的一致性。本篇文章将详细探讨如何解决SVN中的文件冲突。 首先,我们需要理解冲突的产生过程。...
- **冲突解决**:在合并多个分支时,如果存在冲突,DiffMatchPatch可以帮助识别冲突部分,并提供可能的解决方案。 - **文本修复**:例如,自动修复语法错误或拼写错误的工具,可以通过DiffMatchPatch找到问题并...
在PHP中找到两个文本文件之间的快速区别。 例子 可以将Diff呈现为HTML(使用本机方法SimpleDiff::renderDiff($diff) : 主意 该库非常快速地比较两个文本文件,并返回具有差异的对象。 差异处有编号的行,以便于向...
`diff`的基本思想是通过比较两组数据的元素,找到将一个序列转换为另一个序列所需的最少操作数。这些操作可能包括插入、删除和替换。`diff`算法通常分为三个主要步骤: 1. **线性扫描**:首先,对两个文本进行线性...
标签“bin diff”暗示了这是一个二进制差异(binary difference)工具,它可能使用了特定的算法来比较两个二进制文件的字节序列。"PE文件对比/二进制对比"进一步强调了工具的核心功能,即对PE格式的二进制文件进行...
例如,一个开发者发现了一个bug并修复了它,他可以生成一个`.diff`文件,然后将这个文件发送给其他开发者,他们只需应用`patch`即可获取修复。 总的来说,`diff`和`patch`是IT行业中的基础工具,它们帮助开发者和...
Session是一个远程服务器文件操作的会话,可以实现文件的移动、复制、删除等操作。通过使用Session,可以实现远程服务器文件的操作。 6. 使用InputStream和BufferedReader实现命令执行结果的获取 InputStream和...