有谁知道是否有一种简单的方法可以根据模型中的一个字段来制作文件接收器变量的文件名元素路径?因此,不要使用像这样的修复路径:
固定路径/文件名.csv
{variable_path}/文件名.csv
有谁知道是否有一种简单的方法可以根据模型中的一个字段来制作文件接收器变量的文件名元素路径?因此,不要使用像这样的修复路径:
固定路径/文件名.csv
{variable_path}/文件名.csv
附加的 ModelInitializer 显示了如何执行此操作。我还复制了下面的代码,以防附件无法通过。要启用 ModelInitializer,您需要将以下内容添加到 scenario.xml 文件中:
<model.initializer class="PredatorPrey.MyInitializer" />
我在 Predator Prey 演示中对此进行了测试,因此您应该更改类包名称。在 ModelInitializer 示例中,您需要指定与 context.xml 文件中的上下文 ID 相同的根上下文 ID。并且您应该指定变量输出文件夹名称。此示例需要像通常那样在文件接收器中指定文件名,并插入变量路径。需要注意的是,如果场景保存在 GUI 中,变量文件夹路径将保存在场景中,但是此代码将检查任何现有路径并简单地将路径替换为 outputFolder 字符串。因此,您应该将整个路径放在 outputFolder 字符串中,而不仅仅是其中的一部分,或者根据需要更改代码行为。
package PredatorPrey;
import java.io.File;
import repast.simphony.data2.engine.FileSinkComponentControllerAction;
import repast.simphony.data2.engine.FileSinkDescriptor;
import repast.simphony.engine.controller.NullAbstractControllerAction;
import repast.simphony.engine.environment.ControllerAction;
import repast.simphony.engine.environment.RunEnvironmentBuilder;
import repast.simphony.engine.environment.RunState;
import repast.simphony.scenario.ModelInitializer;
import repast.simphony.scenario.Scenario;
import repast.simphony.util.collections.Tree;
public class MyInitializer implements ModelInitializer {
@Override
public void initialize(final Scenario scen, RunEnvironmentBuilder builder) {
scen.addMasterControllerAction(new NullAbstractControllerAction() {
String rootContextID = "Predator Prey";
String outputFolder = "testoutfolder";
@Override
public void batchInitialize(RunState runState, Object contextId) {
Tree<ControllerAction> scenarioTree = scen.getControllerRegistry().getActionTree(rootContextID);
findFileSinkTreeChildren(scenarioTree, scenarioTree.getRoot(), outputFolder);
// Reset the scenario dirty flag so the changes made to the file sink
// descriptors don't prompt a scenario save in the GUI
scen.setDirty(false);
}
});
}
public static void findFileSinkTreeChildren(Tree<ControllerAction> tree,
ControllerAction parent, String outputFolder){
// Check each ControllerAction in the scenario and if it is a FileSink,
// modify the output path to include the folder
for (ControllerAction act : tree.getChildren(parent)){
if (act instanceof FileSinkComponentControllerAction){
FileSinkDescriptor descriptor = ((FileSinkComponentControllerAction)act).getDescriptor();
String fileName = descriptor.getFileName();
// remove any prefix directories from the file name
int lastSeparatorIndex = fileName.lastIndexOf(File.separator);
// Check for backslash separator
if (fileName.lastIndexOf('\\') > lastSeparatorIndex)
lastSeparatorIndex = fileName.lastIndexOf('\\');
// Check for forward slash operator
if (fileName.lastIndexOf('/') > lastSeparatorIndex)
lastSeparatorIndex = fileName.lastIndexOf('/');
if (lastSeparatorIndex > 0){
fileName = fileName.substring(lastSeparatorIndex+1, fileName.length());
}
descriptor.setFileName(outputFolder + File.separator + fileName);
}
else findFileSinkTreeChildren(tree, act, outputFolder);
}
}
}