diff options
author | laszlocsomor <laszlocsomor@google.com> | 2018-07-05 00:17:55 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-07-05 00:19:21 -0700 |
commit | 59f17d6e0550bf63a0b6ef182e2d63474e058ede (patch) | |
tree | 4cbec855321ead722363687b9983685e2b1bf648 /src/main/java/com/google/devtools/build/lib/vfs | |
parent | b40b7e715307de416b786c1d95f6cf3a6b69c9d3 (diff) |
Bazel server: ensure InputStreams are closed
Use try-with-resources to ensure InputStreams that
we open via FileSystem.InputStream(path) are
closed.
Eagerly closing InputStreams avoids hanging on to
file handles until the garbage collector finalizes
the InputStream, meaning Bazel on Windows (and
other processes) can delete or mutate these files.
Hopefully this avoids intermittent file deletion
errors that sometimes occur on Windows.
See https://github.com/bazelbuild/bazel/issues/5512
RELNOTES: none
PiperOrigin-RevId: 203338148
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/vfs')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/vfs/FileSystem.java | 14 | ||||
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java | 54 |
2 files changed, 52 insertions, 16 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/FileSystem.java b/src/main/java/com/google/devtools/build/lib/vfs/FileSystem.java index 8258dccfc0..01c016905f 100644 --- a/src/main/java/com/google/devtools/build/lib/vfs/FileSystem.java +++ b/src/main/java/com/google/devtools/build/lib/vfs/FileSystem.java @@ -268,12 +268,14 @@ public abstract class FileSystem { * @throws IOException if the digest could not be computed for any reason */ protected byte[] getDigest(final Path path, DigestHashFunction hashFunction) throws IOException { - return new ByteSource() { - @Override - public InputStream openStream() throws IOException { - return getInputStream(path); - } - }.hash(hashFunction.getHash()).asBytes(); + try (InputStream in = getInputStream(path)) { + return new ByteSource() { + @Override + public InputStream openStream() throws IOException { + return in; + } + }.hash(hashFunction.getHash()).asBytes(); + } } /** diff --git a/src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java b/src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java index 999c470c8b..e2ab1d8002 100644 --- a/src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java +++ b/src/main/java/com/google/devtools/build/lib/vfs/FileSystemUtils.java @@ -400,7 +400,10 @@ public class FileSystemUtils { throw new IOException("error copying file: " + "couldn't delete destination: " + e.getMessage()); } - asByteSource(from).copyTo(asByteSink(to)); + try (InputStream in = from.getInputStream(); + OutputStream out = to.getOutputStream()) { + ByteStreams.copy(in, out); + } to.setLastModifiedTime(from.getLastModifiedTime()); // Preserve mtime. if (!from.isWritable()) { to.setWritable(false); // Make file read-only if original was read-only. @@ -427,7 +430,10 @@ public class FileSystemUtils { // Fallback to a copy. FileStatus stat = from.stat(Symlinks.NOFOLLOW); if (stat.isFile()) { - asByteSource(from).copyTo(asByteSink(to)); + try (InputStream in = from.getInputStream(); + OutputStream out = to.getOutputStream()) { + ByteStreams.copy(in, out); + } to.setLastModifiedTime(stat.getLastModifiedTime()); // Preserve mtime. if (!from.isWritable()) { to.setWritable(false); // Make file read-only if original was read-only. @@ -817,7 +823,14 @@ public class FileSystemUtils { * @throws IOException if there was an error */ public static Iterable<String> readLines(Path inputFile, Charset charset) throws IOException { - return asByteSource(inputFile).asCharSource(charset).readLines(); + try (InputStream in = inputFile.getInputStream()) { + return new ByteSource() { + @Override + public InputStream openStream() throws IOException { + return in; + } + }.asCharSource(charset).readLines(); + } } /** @@ -826,14 +839,28 @@ public class FileSystemUtils { * @throws IOException if there was an error */ public static byte[] readContent(Path inputFile) throws IOException { - return asByteSource(inputFile).read(); + try (InputStream in = inputFile.getInputStream()) { + return new ByteSource() { + @Override + public InputStream openStream() throws IOException { + return in; + } + }.read(); + } } /** * Reads the entire file using the given charset and returns the contents as a string */ public static String readContent(Path inputFile, Charset charset) throws IOException { - return asByteSource(inputFile).asCharSource(charset).read(); + try (InputStream in = inputFile.getInputStream()) { + return new ByteSource() { + @Override + public InputStream openStream() throws IOException { + return in; + } + }.asCharSource(charset).read(); + } } /** @@ -843,11 +870,18 @@ public class FileSystemUtils { */ public static byte[] readContentWithLimit(Path inputFile, int limit) throws IOException { Preconditions.checkArgument(limit >= 0, "limit needs to be >=0, but it is %s", limit); - ByteSource byteSource = asByteSource(inputFile); - byte[] buffer = new byte[limit]; - try (InputStream inputStream = byteSource.openBufferedStream()) { - int read = ByteStreams.read(inputStream, buffer, 0, limit); - return read == limit ? buffer : Arrays.copyOf(buffer, read); + try (InputStream in = inputFile.getInputStream()) { + byte[] buffer = new byte[limit]; + try (InputStream inputStream = + new ByteSource() { + @Override + public InputStream openStream() throws IOException { + return in; + } + }.openBufferedStream()) { + int read = ByteStreams.read(inputStream, buffer, 0, limit); + return read == limit ? buffer : Arrays.copyOf(buffer, read); + } } } |