1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.car.test.util; 18 19 import android.util.Log; 20 21 import java.io.File; 22 import java.io.FileNotFoundException; 23 import java.io.FileOutputStream; 24 import java.io.IOException; 25 import java.io.InterruptedIOException; 26 27 public final class DiskUtils { 28 private static final String TAG = DiskUtils.class.getSimpleName(); 29 private static final int DISK_DELAY_MS = 4000; 30 31 /** 32 * Writes bytes to a given file 33 * 34 * @param uniqueFile File 35 * @param size Number of bytes to be written 36 * 37 * @return number of bytes written 38 * 39 * @throws IOException Thrown when file doesn't exist or when fos.write fails 40 * @throws InterruptedException Thrown when the current thread is interrupted 41 */ writeToDisk(File uniqueFile, long size)42 public static long writeToDisk(File uniqueFile, long size) 43 throws IOException, InterruptedException { 44 if (!uniqueFile.exists()) { 45 throw new FileNotFoundException("file '" 46 + uniqueFile.getAbsolutePath() + "' doesn't exist"); 47 } 48 49 if (uniqueFile.isDirectory()) { 50 throw new FileNotFoundException(uniqueFile.getAbsolutePath() 51 + " is a directory, not a file."); 52 } 53 54 long writtenBytes = 0; 55 try (FileOutputStream fos = new FileOutputStream(uniqueFile)) { 56 Log.d(TAG, "Attempting to write " + size + " bytes"); 57 writtenBytes = writeToFos(fos, size); 58 fos.getFD().sync(); 59 Thread.sleep(DISK_DELAY_MS); 60 } 61 62 return writtenBytes; 63 } 64 65 /** 66 * Writes bytes to a given filestream 67 * 68 * @param fos Filestream 69 * @param maxSize Number of bytes to be written 70 * 71 * @return number of bytes written 72 * 73 * @throws IOException Thrown when fos.write fails 74 */ writeToFos(FileOutputStream fos, long maxSize)75 private static long writeToFos(FileOutputStream fos, long maxSize) throws IOException { 76 Runtime runtime = Runtime.getRuntime(); 77 long writtenBytes = 0; 78 while (maxSize != 0) { 79 // The total available free memory can be calculated by adding the currently allocated 80 // memory that is free plus the total memory available to the process which hasn't been 81 // allocated yet. 82 long totalFreeMemory = 83 runtime.maxMemory() - runtime.totalMemory() + runtime.freeMemory(); 84 int writeSize = Math.toIntExact(Math.min(totalFreeMemory, maxSize)); 85 Log.i(TAG, "writeSize: " + writeSize); 86 if (writeSize == 0) { 87 Log.d(TAG, 88 "Ran out of memory while writing, exiting early with writtenBytes: " 89 + writtenBytes); 90 return writtenBytes; 91 } 92 try { 93 fos.write(new byte[writeSize]); 94 } catch (InterruptedIOException e) { 95 Thread.currentThread().interrupt(); 96 continue; 97 } 98 maxSize -= writeSize; 99 writtenBytes += writeSize; 100 if (writeSize > 0 && maxSize > 0) { 101 Log.i(TAG, "Total bytes written: " + writtenBytes + "/" 102 + (writtenBytes + maxSize)); 103 } 104 } 105 return writtenBytes; 106 } 107 } 108