• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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