001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.eclipse.aether.internal.test.util; 020 021import java.io.BufferedOutputStream; 022import java.io.File; 023import java.io.FileInputStream; 024import java.io.FileOutputStream; 025import java.io.IOException; 026import java.io.OutputStream; 027import java.io.RandomAccessFile; 028import java.nio.charset.StandardCharsets; 029import java.nio.file.Files; 030import java.util.ArrayList; 031import java.util.Collection; 032import java.util.Properties; 033import java.util.UUID; 034 035/** 036 * Provides utility methods to read and write (temporary) files. 037 */ 038public class TestFileUtils { 039 040 private static final File TMP = new File( 041 System.getProperty("java.io.tmpdir"), 042 "aether-" + UUID.randomUUID().toString().substring(0, 8)); 043 044 static { 045 Runtime.getRuntime().addShutdownHook(new Thread(() -> { 046 try { 047 deleteFile(TMP); 048 } catch (IOException e) { 049 e.printStackTrace(); 050 } 051 })); 052 } 053 054 private TestFileUtils() { 055 // hide constructor 056 } 057 058 @Deprecated 059 public static void deleteTempFiles() throws IOException { 060 deleteFile(TMP); 061 } 062 063 public static void deleteFile(File file) throws IOException { 064 if (file == null) { 065 return; 066 } 067 068 Collection<File> undeletables = new ArrayList<>(); 069 070 delete(file, undeletables); 071 072 if (!undeletables.isEmpty()) { 073 throw new IOException("Failed to delete " + undeletables); 074 } 075 } 076 077 private static void delete(File file, Collection<File> undeletables) { 078 String[] children = file.list(); 079 if (children != null) { 080 for (String child : children) { 081 delete(new File(file, child), undeletables); 082 } 083 } 084 085 if (!del(file)) { 086 undeletables.add(file.getAbsoluteFile()); 087 } 088 } 089 090 private static boolean del(File file) { 091 for (int i = 0; i < 10; i++) { 092 if (file.delete() || !file.exists()) { 093 return true; 094 } 095 } 096 return false; 097 } 098 099 @Deprecated 100 public static boolean mkdirs(File directory) { 101 if (directory == null) { 102 return false; 103 } 104 105 if (directory.exists()) { 106 return false; 107 } 108 if (directory.mkdir()) { 109 return true; 110 } 111 112 File canonDir = null; 113 try { 114 canonDir = directory.getCanonicalFile(); 115 } catch (IOException e) { 116 return false; 117 } 118 119 File parentDir = canonDir.getParentFile(); 120 return (parentDir != null && (mkdirs(parentDir) || parentDir.exists()) && canonDir.mkdir()); 121 } 122 123 /** 124 * @throws IOException if an I/O error occurs 125 * @deprecated use @TempDir (JUnit 5) Or TemporaryFolder (JUnit 4) instead 126 */ 127 @Deprecated 128 public static File createTempFile(String contents) throws IOException { 129 return createTempFile(contents.getBytes(StandardCharsets.UTF_8), 1); 130 } 131 132 @Deprecated 133 /** 134 * @throws IOException if an I/O error occurs 135 * @deprecated use @TempDir (JUnit 5) Or TemporaryFolder (JUnit 4) instead 136 */ 137 public static File createTempFile(byte[] pattern, int repeat) throws IOException { 138 mkdirs(TMP); 139 File tmpFile = File.createTempFile("tmpfile-", ".data", TMP); 140 writeBytes(tmpFile, pattern, repeat); 141 return tmpFile; 142 } 143 144 /** 145 * Creates a temporary directory. 146 * 147 * @return the temporary directory 148 * @throws IOException if an I/O error occurs 149 * @deprecated use @TempDir (JUnit 5) Or TemporaryFolder (JUnit 4) instead 150 */ 151 @Deprecated 152 public static File createTempDir() throws IOException { 153 return createTempDir(""); 154 } 155 156 /** 157 * Creates a temporary directory. 158 * 159 * @return the temporary directory 160 * @throws IOException if an I/O error occurs 161 * @deprecated use {@code @TempDir} (JUnit 5) or {@code TemporaryFolder} (JUnit 4) instead 162 */ 163 @Deprecated 164 public static File createTempDir(String suffix) throws IOException { 165 mkdirs(TMP); 166 File tmpFile = File.createTempFile("tmpdir-", suffix, TMP); 167 deleteFile(tmpFile); 168 mkdirs(tmpFile); 169 return tmpFile; 170 } 171 172 public static long copyFile(File source, File target) throws IOException { 173 long total = 0; 174 175 FileInputStream fis = null; 176 OutputStream fos = null; 177 try { 178 fis = new FileInputStream(source); 179 180 mkdirs(target.getParentFile()); 181 182 fos = new BufferedOutputStream(new FileOutputStream(target)); 183 184 for (byte[] buffer = new byte[1024 * 32]; ; ) { 185 int bytes = fis.read(buffer); 186 if (bytes < 0) { 187 break; 188 } 189 190 fos.write(buffer, 0, bytes); 191 192 total += bytes; 193 } 194 195 fos.close(); 196 fos = null; 197 198 fis.close(); 199 fis = null; 200 } finally { 201 try { 202 if (fos != null) { 203 fos.close(); 204 } 205 } catch (final IOException e) { 206 // Suppressed due to an exception already thrown in the try block. 207 } finally { 208 try { 209 if (fis != null) { 210 fis.close(); 211 } 212 } catch (final IOException e) { 213 // Suppressed due to an exception already thrown in the try block. 214 } 215 } 216 } 217 218 return total; 219 } 220 221 /** 222 * Reads the contents of a file into a byte array. 223 * 224 * @param file the file to read 225 * @return the contents of the file as a byte array 226 * @throws IOException if an I/O error occurs 227 * @deprecated use {@code Files.readAllBytes(Path)} instead 228 */ 229 @Deprecated 230 public static byte[] readBytes(File file) throws IOException { 231 RandomAccessFile in = null; 232 try { 233 in = new RandomAccessFile(file, "r"); 234 byte[] actual = new byte[(int) in.length()]; 235 in.readFully(actual); 236 in.close(); 237 in = null; 238 return actual; 239 } finally { 240 try { 241 if (in != null) { 242 in.close(); 243 } 244 } catch (final IOException e) { 245 // Suppressed due to an exception already thrown in the try block. 246 } 247 } 248 } 249 250 @Deprecated 251 public static void writeBytes(File file, byte[] pattern, int repeat) throws IOException { 252 file.deleteOnExit(); 253 file.getParentFile().mkdirs(); 254 OutputStream out = null; 255 try { 256 out = new BufferedOutputStream(new FileOutputStream(file)); 257 for (int i = 0; i < repeat; i++) { 258 out.write(pattern); 259 } 260 out.close(); 261 out = null; 262 } finally { 263 try { 264 if (out != null) { 265 out.close(); 266 } 267 } catch (final IOException e) { 268 // Suppressed due to an exception already thrown in the try block. 269 } 270 } 271 } 272 273 public static String readString(File file) throws IOException { 274 byte[] content = Files.readAllBytes(file.toPath()); 275 return new String(content, StandardCharsets.UTF_8); 276 } 277 278 @Deprecated 279 public static void writeString(File file, String content) throws IOException { 280 writeBytes(file, content.getBytes(StandardCharsets.UTF_8), 1); 281 } 282 283 @Deprecated 284 public static void writeString(File file, String content, long timestamp) throws IOException { 285 writeBytes(file, content.getBytes(StandardCharsets.UTF_8), 1); 286 file.setLastModified(timestamp); 287 } 288 289 public static void readProps(File file, Properties props) throws IOException { 290 FileInputStream fis = null; 291 try { 292 fis = new FileInputStream(file); 293 props.load(fis); 294 fis.close(); 295 fis = null; 296 } finally { 297 try { 298 if (fis != null) { 299 fis.close(); 300 } 301 } catch (final IOException e) { 302 // Suppressed due to an exception already thrown in the try block. 303 } 304 } 305 } 306 307 public static void writeProps(File file, Properties props) throws IOException { 308 file.getParentFile().mkdirs(); 309 310 FileOutputStream fos = null; 311 try { 312 fos = new FileOutputStream(file); 313 props.store(fos, "aether-test"); 314 fos.close(); 315 fos = null; 316 } finally { 317 try { 318 if (fos != null) { 319 fos.close(); 320 } 321 } catch (final IOException e) { 322 // Suppressed due to an exception already thrown in the try block. 323 } 324 } 325 } 326}