MATSIM
OutputDirectoryHierarchy.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * OutputDirectoryHierarchy.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2009 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 package org.matsim.core.controler;
21 
22 import java.io.File;
23 import java.io.IOException;
24 import java.nio.file.Files;
25 import java.nio.file.Path;
26 import java.util.Comparator;
27 import java.util.stream.Stream;
28 
29 import org.apache.logging.log4j.LogManager;
30 import org.apache.logging.log4j.Logger;
31 import org.matsim.core.config.Config;
33 import org.matsim.core.utils.io.IOUtils;
34 
35 import jakarta.inject.Inject;
36 
44 public final class OutputDirectoryHierarchy {
45 
46  public enum OverwriteFileSetting {failIfDirectoryExists, overwriteExistingFiles, deleteDirectoryIfExists}
47 
48  private static final String DIRECTORY_ITERS = "ITERS";
49 
50  public static final String MATSIM_TEMP_DIR_PROPERTY = "matsim.tempDir";
51 
52  private static final Logger log = LogManager.getLogger(OutputDirectoryHierarchy.class);
53 
54  private String runId = null;
55 
56  private final String outputPath;
57 
59 
61 
62  @Inject
64 
65  this(config.getOutputDirectory(),
66  config.getRunId(),
67  config.getOverwriteFileSetting(),
68  config.getCompressionType());
69  }
70 
76  public OutputDirectoryHierarchy( Config config ) {
78  }
79 
82  }
83 
86  }
94  public OutputDirectoryHierarchy(String outputPath, String runId, OverwriteFileSetting overwriteFiles, boolean createDirectories, ControllerConfigGroup.CompressionType compressionType){
95  this.overwriteFiles = overwriteFiles;
96  if (outputPath.endsWith("/")) {
97  outputPath = outputPath.substring(0, outputPath.length() - 1);
98  }
99  this.outputPath = outputPath;
100  this.runId = runId;
101  this.defaultCompressionType = compressionType;
102  if (createDirectories){
103  this.createDirectories();
104  }
105  }
106 
112  public final String getTempPath() {
113  String matsimTempDir = System.getProperty(MATSIM_TEMP_DIR_PROPERTY);
114  if (matsimTempDir == null) {
115  matsimTempDir = outputPath + "/tmp";
116  }
117  return matsimTempDir;
118  }
119 
128  public final String getIterationPath(final int iteration) {
129  return outputPath + "/" + DIRECTORY_ITERS + "/it." + iteration;
130  }
131 
140  public final String getIterationFilename(final int iteration, final String filename) {
141  StringBuilder s = new StringBuilder(getIterationPath(iteration));
142  s.append('/');
143  if (runId != null) {
144  s.append(runId);
145  s.append('.');
146  }
147  s.append(iteration);
148  s.append(".");
149  s.append(filename);
150  return s.toString();
151  }
152 
153  public String getIterationFilename(int iteration, String filename, ControllerConfigGroup.CompressionType compression) {
154  if (compression == null) {
155  return getIterationFilename(iteration, filename);
156  }
157  return getIterationFilename(iteration, filename + compression.fileEnding);
158  }
159 
160  public final String getIterationFilename(int iteration, Controler.DefaultFiles file) {
161  return getIterationFilename(iteration, file, this.defaultCompressionType);
162  }
163 
164  public final String getIterationFilename(int iteration, Controler.DefaultFiles file, ControllerConfigGroup.CompressionType compression) {
165  if (compression == null) {
166  return getIterationFilename(iteration, file.filename);
167  }
168  return getIterationFilename(iteration, file.filename + compression.fileEnding);
169  }
170 
178  public final String getOutputFilename(final String filename) {
179  StringBuilder s = new StringBuilder(outputPath);
180  s.append('/');
181  if (runId != null) {
182  s.append(runId);
183  s.append('.');
184  }
185  s.append(filename);
186  return s.toString();
187  }
188 
189  public String getOutputFilename(String filename, ControllerConfigGroup.CompressionType compression) {
190  if (compression == null) {
191  return getOutputFilename(filename);
192  }
193  return getOutputFilename(filename + compression.fileEnding);
194  }
195 
196  public final String getOutputFilenameWithOutputPrefix(final String filename) {
197  return getOutputFilename(Controler.OUTPUT_PREFIX + filename);
198  }
199 
200  public final String getOutputFilename(Controler.DefaultFiles file) {
201  return getOutputFilename(file, this.defaultCompressionType);
202  }
203 
205  if (compression == null) {
206  return getOutputFilename(Controler.OUTPUT_PREFIX + file.filename);
207  }
208  return getOutputFilename(Controler.OUTPUT_PREFIX + file.filename + compression.fileEnding);
209  }
210 
211 
212  public String getOutputPath() {
213  return outputPath;
214  }
215 
219  public final void createIterationDirectory(final int iteration) {
220  File dir = new File(getIterationPath(iteration));
221  if (!dir.mkdir()) {
222  if (this.overwriteFiles == OverwriteFileSetting.overwriteExistingFiles && dir.exists()) {
223  log.info("Iteration directory "
224  + getIterationPath(iteration)
225  + " exists already.");
226  } else {
227  log.warn("Could not create iteration directory "
228  + getIterationPath(iteration) + ".");
229  }
230  }
231  }
232 
236  public void deleteIterationDirectory() {
237 
238  Path path = Path.of(outputPath + "/" + DIRECTORY_ITERS);
239  try (Stream<Path> stream = Files.walk(path)) {
240  stream
241  .sorted(Comparator.reverseOrder())
242  .map(Path::toFile)
243  .forEach(File::delete);
244  } catch (IOException e) {
245  log.warn("Could not delete iteration directory " + path + ".");
246  }
247  }
248 
249  private void createDirectories() {
250  File outputDir = new File(outputPath);
251  if (outputDir.exists()) {
252  if (outputDir.isFile()) {
253  throw new RuntimeException("Cannot create output directory. "
254  + outputPath + " is a file and cannot be replaced by a directory.");
255  }
256  if (outputDir.list().length > 0) {
257  switch ( overwriteFiles ) {
258  case failIfDirectoryExists:
259  // the directory is not empty, we do not overwrite any
260  // files!
261  throw new RuntimeException(
262  "The output directory " + outputPath
263  + " (full path: "
264  + outputDir.getAbsolutePath()
265  +")"
266  + " already exists and is not empty!"
267  + " Please either delete or empty the directory or"
268  + " configure the services via setOverwriteFileSetting()"
269  + " or the \"overwriteFiles\" parameter of the \"services\" config group.");
270  case overwriteExistingFiles:
271  System.out.flush();
272  log.warn("###########################################################");
273  log.warn("### THE CONTROLER WILL OVERWRITE FILES IN:");
274  log.warn("### " + outputPath);
275  log.warn("### full path: " + outputDir.getAbsolutePath());
276  log.warn("###########################################################");
277  System.err.flush();
278  break;
279  case deleteDirectoryIfExists:
280  // log a warning, even if at the time the user sees it,
281  // it is too late to change his mind...
282  // I still have problems understanding why people want such a setting.
283  System.out.flush();
284  log.info("###########################################################");
285  log.info("### THE CONTROLER WILL DELETE THE EXISTING OUTPUT DIRECTORY:");
286  log.info("### " + outputPath);
287  log.warn("### full path: " + outputDir.getAbsolutePath());
288  log.info("###########################################################");
289  System.out.flush();
290  IOUtils.deleteDirectoryRecursively(outputDir.toPath());
291  break;
292  default:
293  throw new RuntimeException( "unknown setting "+overwriteFiles );
294  }
295  }
296  }
297 
298  if (!outputDir.exists() && !outputDir.mkdirs()) {
299  throw new RuntimeException(
300  "The output directory path " + outputPath
301  + " could not be created. Check pathname and permissions! Full path: " + new File(outputPath).getAbsolutePath());
302  }
303 
304  File tmpDir = new File(getTempPath());
305  if (!tmpDir.mkdir() && !tmpDir.exists()) {
306  throw new RuntimeException("The tmp directory "
307  + getTempPath() + " could not be created.");
308  }
309  File itersDir = new File(outputPath + "/" + Controler.DIRECTORY_ITERS);
310  if (!itersDir.mkdir() && !itersDir.exists()) {
311  throw new RuntimeException("The iterations directory "
312  + (outputPath + "/" + Controler.DIRECTORY_ITERS)
313  + " could not be created.");
314  }
315  }
316 
317 }
static void deleteDirectoryRecursively(Path path)
Definition: IOUtils.java:446
final String getIterationFilename(final int iteration, final String filename)
final String getOutputFilenameWithOutputPrefix(final String filename)
final ControllerConfigGroup.CompressionType defaultCompressionType
final String getOutputFilename(Controler.DefaultFiles file)
OutputDirectoryHierarchy(String outputPath, OverwriteFileSetting overwriteFiles, ControllerConfigGroup.CompressionType defaultCompressionType)
OutputDirectoryHierarchy(String outputPath, String runId, OverwriteFileSetting overwriteFiles, ControllerConfigGroup.CompressionType defaultCompressionType)
String getOutputFilename(String filename, ControllerConfigGroup.CompressionType compression)
static final String DIRECTORY_ITERS
Definition: Controler.java:73
final String getOutputFilename(Controler.DefaultFiles file, ControllerConfigGroup.CompressionType compression)
String getIterationFilename(int iteration, String filename, ControllerConfigGroup.CompressionType compression)
final ControllerConfigGroup controller()
Definition: Config.java:399
final String getIterationFilename(int iteration, Controler.DefaultFiles file)
OutputDirectoryHierarchy(String outputPath, String runId, OverwriteFileSetting overwriteFiles, boolean createDirectories, ControllerConfigGroup.CompressionType compressionType)
final String getIterationFilename(int iteration, Controler.DefaultFiles file, ControllerConfigGroup.CompressionType compression)