所以我使用以下命令在文件上创建一个锁,以便我可以独占编辑它:
File file = new File(filename);
channel = new RandomAccessFile(file, "rw").getChannel();
lock = channel.tryLock();
Run Code Online (Sandbox Code Playgroud)
现在我有第二个线程想要访问同一个文件 - 只是为了阅读,而不是编辑.我怎么做?现在第二个线程将抛出一个io异常并通知我该文件已被锁定.
这可行吗?有什么建议?谢谢
每当我从fileURI开始 Camel 路由时,我都会看到 Camel 获得了文件的“锁定”。例如,如果文件名为myinput.xml,则 Camel 在其上创建一个名为.lock 的“锁定文件”,位于同一目录中myinput.xml.camelLock。
我正在尝试使用FileLock在Windows环境中使用Java锁定文件,我遇到了一个问题:在我锁定文件之后,至少在某种程度上它仍然可以被其他进程访问.
示例代码如下:
public class SimpleLockExample {
public static void main(String[] args) throws Exception {
String filename = "loremlipsum.txt";
File file = new File(filename);
RandomAccessFile raf = new RandomAccessFile(file, "rw");
FileChannel channel = raf.getChannel();
FileLock lock = null;
try {
lock = channel.tryLock();
String firstLine = raf.readLine();
System.out.println("First line of file : " + firstLine);
waitForEnter();
lock.release();
} catch (OverlappingFileLockException e) {
e.printStackTrace();
}
lock.release();
System.out.println("Lock released");
channel.close();
}
private static void waitForEnter() throws Exception {
BufferedReader reader = …Run Code Online (Sandbox Code Playgroud) 我正在IO.Directory.GetFiles用来搜索文件夹中的文件.搜索完成后,在我的应用程序关闭之前,我无法使用此文件夹中的文件.我没有Dispose在DirectoryInfo课堂上找到任何功能,所以我的问题是:如何释放或解锁这些文件?
我的代码:
Dim list = IO.Directory.GetFiles(folder, "*.*", IO.SearchOption.AllDirectories)
Run Code Online (Sandbox Code Playgroud)
编辑:
我已经非常仔细地检查了我的代码(我无法在另一个项目中重现我的问题),事实证明这个函数是锁定文件:
Public Function ComputeFileHash(ByVal filePath As String)
Dim md5 As MD5CryptoServiceProvider = New MD5CryptoServiceProvider
Dim f As FileStream = New FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
f = New FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 8192)
md5.ComputeHash(f)
f.Close()
f.Dispose()
Dim hash As Byte() = md5.Hash
Dim buff As Text.StringBuilder = New Text.StringBuilder
Dim hashByte As Byte
For Each hashByte In hash
buff.Append(String.Format("{0:X2}", hashByte))
Next
Dim md5string As String …Run Code Online (Sandbox Code Playgroud) 我有一个返回PrivateFontCollection的函数:
Public Shared Function GetCustomFonts() As PrivateFontCollection
Dim result = New PrivateFontCollection
Dim customFontFiles = {"Garamond.TTF", "Garamond-Bold.TTF", "Garamond-Italic.TTF", "EurostileExtended-Roman-DTC.TTF"}
For Each fontFile In customFontFiles
result.AddFontFile(Hosting.HostingEnvironment.MapPath("/Includes/" & fontFile))
Next
Return result
End Function
Run Code Online (Sandbox Code Playgroud)
然后我使用如下函数:
Using customFonts = Common.GetCustomFonts()
' Do some stuff here
End Using
Run Code Online (Sandbox Code Playgroud)
我希望文件将被释放,但它们仍然被锁定:我收到以下错误:'操作无法完成,因为文件在System中打开.关闭文件,然后重试.
在IIS中关闭网站没有帮助; 我们必须回收应用程序池才能发布它.
任何人都可以建议如何使用PrivateFontCollection这样的方式使文件在使用之间释放?
我在运行RHEL7的服务器上安装了Mediawiki v1.24.1.我在/ var/www/foohelp/wiki下安装了它.但是,当我尝试上传文件时,出现以下错误:
[f3eae72a] /foohelp/wiki/index.php/Special:Upload Exception from line 1871 of /var/www/foohelp/mediawiki-1.24.1/includes/filerepo/file/LocalFile.php: Could not acquire lock for 'User-default.png.'
Backtrace:
#0 /var/www/foohelp/mediawiki-1.24.1/includes/filerepo/file/LocalFile.php(1174): LocalFile->lock()
#1 /var/www/foohelp/mediawiki-1.24.1/includes/upload/UploadBase.php(738): LocalFile->upload(string, string, string, integer, array, boolean, User)
#2 /var/www/foohelp/mediawiki-1.24.1/includes/specials/SpecialUpload.php(467): UploadBase->performUpload(string, string, boolean, User)
#3 /var/www/foohelp/mediawiki-1.24.1/includes/specials/SpecialUpload.php(186): SpecialUpload->processUpload()
#4 /var/www/foohelp/mediawiki-1.24.1/includes/specialpage/SpecialPage.php(363): SpecialUpload->execute(NULL)
#5 /var/www/foohelp/mediawiki-1.24.1/includes/specialpage/SpecialPageFactory.php(584): SpecialPage->run(NULL)
#6 /var/www/foohelp/mediawiki-1.24.1/includes/MediaWiki.php(275): SpecialPageFactory::executePath(Title, RequestContext)
#7 /var/www/foohelp/mediawiki-1.24.1/includes/MediaWiki.php(584): MediaWiki->performRequest()
#8 /var/www/foohelp/mediawiki-1.24.1/includes/MediaWiki.php(435): MediaWiki->main()
#9 /var/www/foohelp/mediawiki-1.24.1/index.php(46): MediaWiki->run()
#10 {main}
Run Code Online (Sandbox Code Playgroud)
如果我编辑/includes/filebackend/FileBackendGroup.php并将LockManager修改为
'lockManager' => 'fsLockManager',
Run Code Online (Sandbox Code Playgroud)
并修改权限如下:
chown -R apache:apache images/
chown -R 755 images/
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
(Could not create directory "mwstore://local-backend/local-public)
Run Code Online (Sandbox Code Playgroud)
我已经尝试了大多数论坛,似乎没有解决方案可以解决我的问题.任何帮助,将不胜感激.
根据文档,AWS EFS(亚马逊弹性文件系统)支持文件锁定:
Amazon EFS 提供文件系统接口和文件系统访问语义(例如强数据一致性和文件锁定)。
在本地文件系统(例如 ext4)上,flock可用于在 shell 脚本中创建临界区。例如,这个答案描述了我过去使用的一种模式:
#!/bin/bash
(
# Wait for lock on /var/lock/.myscript.exclusivelock (fd 200) for 10 seconds
flock -x -w 10 200 || exit 1
# Do stuff
) 200>/var/lock/.myscript.exclusivelock
Run Code Online (Sandbox Code Playgroud)
可以在 EFS 上应用相同的模式吗?Amazon 提到他们使用的是 NFSv4 协议,但它是否提供与flockext4相同的保证?
如果不是,您如何强制执行一个操作以专门在附加到同一 EFS 卷的所有 EC2 实例上运行?如果它适用于进程就足够了,因为我不打算运行多个线程。
还是我误解了 NFSv4 中提供的锁定支持?不幸的是,我不知道协议的细节,但是在分布式系统中提供原子性比在本地机器上要困难得多。
更新:小规模实验
当然,这不是证明,但在我的测试中,它适用于多个实例。目前,我认为该模式可以安全使用。不过,很高兴知道它在理论上是否合理。
我正在开发一个与USPS运输包名为Dazzle的系统.该系统的一部分包括一个监视守护进程,其目的是获取制表符分隔的值文件,将它们转换为Dazzle识别的XML,并将它们传递给Dazzle以生成标签.这部分工作得很好.但是,我还想要解析Dazzle生成的输出文件并将其导入数据库.
请注意,Dazzle在Windows上运行.我的监控守护进程是用Perl编写的,可以在Linux上运行.我的Linux系统通过Samba安装了Dazzle的输入和输出目录.
Dazzle开始写入输出文件的时间和完成的时间之间存在可测量的延迟.我想知道的是我如何等待Dazzle完成输出文件的编写?我已经尝试打开文件并对其进行flock($fh, LOCK_SH)操作,但这似乎没有任何好处.
编辑:我有一个基于"mobrule"的评论的想法如下.Dazzle用XML编写输出文件.货件中的每个包装都包含在标签中,整个文件都包含在标签中.所以,如果我在文件完成之前就开始阅读文件,我可以在采取行动之前等待合适的结束标记.
另外,我应该提一下我目前正在做的事情.当我检测到已创建输出XML文件时,我尝试解析它.如果解析失败,我会睡觉并再试一次.如果失败了,我会睡两次,然后再试一次,依此类推.这在64秒超时的测试中运行良好.
我正在创建一个用于打开和编辑xml文件的简单应用程序.这些文件位于由多个应用程序实例访问的本地文件夹中.我想要做的是锁定由应用程序实例打开的每个文件,以便其他实例无法访问它.
为此,我使用以下代码:
function void readFile(){
File xmlFile = new File("myFile.xml");
RandomAccessFile raf = new RandomAccessFile(xmlFile, "rw");
FileLock fl = raf.getChannel().tryLock();
if(fl==null){
System.out.println("file already locked by another instance");
}else{
setCurrentFile(raf);
setLock(fl);
System.out.println("file successfully locked by this instance");
}
Run Code Online (Sandbox Code Playgroud)
}
因为我想保持对正在编辑的文件的锁定持续时间我不关闭raf也不释放fl.
此时,尝试访问锁定文件的应用程序的任何其他实例都无法执行此操作.到现在为止还挺好.
我观察到以下奇怪的事情:
如果在获取文件锁定后,我在同一文件上打开FileInputStream,即使FileLock对象仍然有效(isValid返回true),应用程序的其他实例现在可以访问正在编辑的文件.
我觉得这个行为很奇怪.谁能解释为什么会这样?
我希望上述内容有道理.提前致谢!
我遇到了这种情况,却不明白为什么会这样。有人可以帮我理解nio文件锁定的行为。
我使用FileOutputStream打开了一个文件,并使用nio FileLock获得了排他锁之后,我将一些数据写入了文件中。没有释放锁。试图在同一文件上打开另一个FileOutputStream以获取锁并执行写操作,并期望此操作会失败。但是打开第二个fileoutputstream会覆盖已经写入数据的已经锁定的文件,甚至在我尝试获得第二个锁之前。这是预期的吗?我的理解是获得排他锁将防止对锁定文件进行任何更改。尝试获取另一个锁定时,如何防止覆盖文件?(就好像另一个进程试图在另一个vm上的同一文件上获得锁一样?)
我尝试过的示例程序:
File fileToWrite = new File("C:\\temp\\myfile.txt");
FileOutputStream fos1 = new FileOutputStream(fileToWrite);
FileOutputStream fos2 =null;
FileLock lock1,lock2 =null;
lock1=fos1.getChannel().tryLock();
if(lock1!=null){
//wrote date to myfile.txt after acquiring lock
fos1.write(data.getBytes());
//opened myfile.txt again and this replaced the file
fos2 = new FileOutputStream(fileToWrite);
//got an overlappingfilelock exception here
lock2=fos2.getChannel().tryLock();
fos2.write(newdata.getBytes());
}
lock1.release();
fos1.close();
if(lock2!=null)
lock2.release();
fos2.close();
Run Code Online (Sandbox Code Playgroud)
还尝试将以上内容分成两个程序。从1st开始执行,并在1st等待时开始执行。被program1锁定的文件被program2覆盖。示例如下:
程序1:
File fileToWrite = new File("C:\\temp\\myfile.txt");
FileOutputStream fos1 = new FileOutputStream(fileToWrite);
FileLock lock1 =null;
lock1=fos1.getChannel().tryLock();
if(lock1!=null){
//wrote date to myfile.txt after acquiring lock
fos1.write(data.getBytes()); …Run Code Online (Sandbox Code Playgroud) filelock ×10
java ×5
file-io ×2
vb.net ×2
amazon-efs ×1
apache-camel ×1
asp.net ×1
concurrency ×1
dispose ×1
file-locking ×1
file-upload ×1
getfiles ×1
linux ×1
mediawiki ×1
nfs ×1
perl ×1
samba ×1
windows ×1