如何使用java为Windows虚拟机上的其他用户管理文件权限



我正在编写一个Jmeter脚本,并在JSR223采样器中控制一些文件处理。问题是我需要创建一个本地文件,但如果该文件名已经存在,我想在重新创建之前删除它。我的代码在我的笔记本电脑(Windows 10(上运行良好,但我现在正在将Jmeter脚本移植到测试环境中的虚拟机中,这似乎是问题的一部分。虚拟机运行的是Windows Server 2019,但这是学术性的。我使用我的标准内部公司证书对那台机器进行RDC。

我的问题是:如何强制删除文件,或者单独修改其系统访问权限,以便继续删除。

我是一个Java程序员新手,但除此之外,我还是一个经验丰富的集成者,在许多编程语言方面有着30多年的丰富经验。

Java版本:

  • 我的本地机器:v8更新261
  • 虚拟机:v8更新261

Jmeter版本:

  • 我的本地机器:Jmeter 5.2.1
  • 虚拟机:Jmeter 5.3

根本原因似乎是在虚拟机上,当我的Jmeter任务创建文件,然后我在Windows资源管理器中检查它时:我的帐户具有完全权限,而主机上的本地"用户"帐户只有读取权限(请参阅随附的屏幕截图(。在我的代码需要删除文件的情况下,Jmeter脚本似乎只访问只读版本,因此无法删除或覆盖它。
每个不同用户的文件属性

请注意,如果我在Windows中手动编辑访问属性,使本地用户具有完全访问权限,那么我的代码运行时不会出现任何问题,文件也会被删除。

当达到删除方法时,我的控制台日志报告以下消息:

JSR223Sampler:JSR223脚本中的问题构建plink脚本文件(BSSMNP文件(,消息:javax.script.ScriptException:java.io.FileNotFoundException:D:\SLAB Automation\JmeterScripts\Scripts\check_bss_mnp_BRP_files.link(访问被拒绝(

这是我的代码,它是Groovy脚本引擎中的Java。

//  if the file exists. If it does, delete it and recreate it.
f= new File(fPath);
if (f.exists()) { 
log.info("File " + fName + " exists.. deleting it.");
System.gc();            // Run Garbage collection (Found a solution that suggests to do this, but it makes no difference)
f.setWritable(true);    // Try modifying the permissions; also fails.
f.delete();             // *** Here is my problem ***
} 
// Open File 
f = new FileOutputStream(fPath, false);     // Second param: true to append; false to overwrite (what we want)
p = new PrintStream(f); 
// Write data to file 
p.println( "*** my content ***");
// Close File(s)
p.close();
f.close();
log.info("-- Created file: " + fPath);

对于任何需要堆栈跟踪的人来说,这里是为了完整性:

2020-09-09 18:32:21,317 ERROR o.a.j.p.j.s.JSR223Sampler: Problem in JSR223 script Build plink Script File (BSS MNP File ), message: javax.script.ScriptException: java.io.FileNotFoundException: D:SLAB AutomationJmeter Scriptsscriptscheck_bss_mnp_BRP_files.plink (Access is denied)
javax.script.ScriptException: java.io.FileNotFoundException: D:SLAB AutomationJmeter Scriptsscriptscheck_bss_mnp_BRP_files.plink (Access is denied)
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:320) ~[groovy-jsr223-3.0.3.jar:3.0.3]
at org.codehaus.groovy.jsr223.GroovyCompiledScript.eval(GroovyCompiledScript.java:71) ~[groovy-jsr223-3.0.3.jar:3.0.3]
at javax.script.CompiledScript.eval(Unknown Source) ~[?:1.8.0_261]
at org.apache.jmeter.util.JSR223TestElement.processFileOrScript(JSR223TestElement.java:222) ~[ApacheJMeter_core.jar:5.3]
at org.apache.jmeter.protocol.java.sampler.JSR223Sampler.sample(JSR223Sampler.java:72) [ApacheJMeter_java.jar:5.3]
at org.apache.jmeter.threads.JMeterThread.doSampling(JMeterThread.java:630) [ApacheJMeter_core.jar:5.3]
at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:558) [ApacheJMeter_core.jar:5.3]
at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:489) [ApacheJMeter_core.jar:5.3]
at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:256) [ApacheJMeter_core.jar:5.3]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_261]
Caused by: java.io.FileNotFoundException: D:SLAB AutomationJmeter Scriptsscriptscheck_bss_mnp_BRP_files.plink (Access is denied)
at java.io.FileOutputStream.open0(Native Method) ~[?:1.8.0_261]
at java.io.FileOutputStream.open(Unknown Source) ~[?:1.8.0_261]
at java.io.FileOutputStream.<init>(Unknown Source) ~[?:1.8.0_261]
at java.io.FileOutputStream.<init>(Unknown Source) ~[?:1.8.0_261]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_261]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) ~[?:1.8.0_261]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) ~[?:1.8.0_261]
at java.lang.reflect.Constructor.newInstance(Unknown Source) ~[?:1.8.0_261]
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:72) ~[groovy-3.0.3.jar:3.0.3]
at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105) ~[groovy-3.0.3.jar:3.0.3]
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:59) ~[groovy-3.0.3.jar:3.0.3]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:263) ~[groovy-3.0.3.jar:3.0.3]
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:286) ~[groovy-3.0.3.jar:3.0.3]
at Script115.run(Script115.groovy:40) ~[?:?]
at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:317) ~[groovy-jsr223-3.0.3.jar:3.0.3]
... 9 more

您能执行以下操作并检查它是否有效吗?

  1. 确保目录/文件夹D:\SLAB Automation\Jmeter Scripts\Scripts\在执行Jmeter脚本的计算机中退出

避免在目录/文件夹名称中使用空格是一种很好的做法。您可以删除目录中的空格,并相应地更新测试计划。

  1. 请确保登录的用户有权将文件读/写到系统中。根据您的输入,看起来您在这里没有任何问题

  2. 您是否可以尝试使用类似IntelliJ的Java IDE想法运行groovy脚本,并确认您的脚本也在您的VM上运行。

我希望这对你有用。

我决定解决我的问题,而不是按照我最初考虑的方式解决它。我想知道是否有任何Java方法可以戳到Windows操作系统级别来提升文件权限或覆盖它们。我知道Java是一个虚拟机,它鼓励可移植代码,因此这样的解决方案是违背精神的。此外,这远远超出了我的Java知识范围。

无论如何,我意识到我需要创建的文件也需要特定于正在进行的测试运行。由于我的Jmeter脚本变得更加复杂,甚至可能有多个线程组并行运行,我不希望两个TG为了不同的目的使用相同的文件名时出现竞争条件。

解决方案:每个上下文和测试运行都有唯一的文件名。我将它们存储在TempFiles专用的文件夹中,甚至在其中动态创建每月的子文件夹,以帮助在主机上进行文件管理。它在起作用,这是最重要的。

最新更新