Skip to content

Commit 59e1bda

Browse files
authored
Improve file handling on Windows (#3764)
Changes: - replace `new FileInputStream` with `Files.newInputStream` - replace `new FileOutputStream` with `Files.newOutputStream` Motivation: #1939 https://bugs.openjdk.org/browse/JDK-6357433 (in a comment) says: > For jdk7, the workaround is to **use new file system API**. So instead of new FileInputStream(f) and new FileOutputStream(f), use f.toPath().newInputStream() and f.toPath().newOutputStream() So seems like new NIO API does use, FILE_SHARE_DELETE, which is needed to delete files in unix-style.
1 parent 2a5a13d commit 59e1bda

File tree

9 files changed

+35
-35
lines changed

9 files changed

+35
-35
lines changed

contrib/sonatypecentral/src/mill/contrib/sonatypecentral/SonatypeCentralPublisher.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import mill.api.Logger
1010
import mill.scalalib.publish.Artifact
1111
import mill.scalalib.publish.SonatypeHelpers.getArtifactMappings
1212

13-
import java.io.FileOutputStream
13+
import java.nio.file.Files
1414
import java.util.jar.JarOutputStream
1515
import java.util.zip.ZipEntry
1616

@@ -110,15 +110,15 @@ class SonatypeCentralPublisher(
110110
wd: os.Path
111111
)(func: JarOutputStream => Unit): java.io.File = {
112112
val zipFile =
113-
(wd / s"$fileNameWithoutExtension.zip").toIO
114-
val fileOutputStream = new FileOutputStream(zipFile)
113+
(wd / s"$fileNameWithoutExtension.zip")
114+
val fileOutputStream = Files.newOutputStream(zipFile.toNIO)
115115
val jarOutputStream = new JarOutputStream(fileOutputStream)
116116
try {
117117
func(jarOutputStream)
118118
} finally {
119119
jarOutputStream.close()
120120
}
121-
zipFile
121+
zipFile.toIO
122122
}
123123

124124
private def zipFilesToJar(

main/api/src/mill/api/IO.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package mill.api
22

3+
import java.nio.file.Files
4+
35
/**
46
* Misc IO utilities, eventually probably should be pushed upstream into
57
* ammonite-ops
@@ -29,7 +31,7 @@ object IO extends StreamSupport {
2931
if (!entry.isDirectory) {
3032
val entryDest = ctx.dest / dest / os.SubPath(entry.getName)
3133
os.makeDir.all(entryDest / os.up)
32-
val fileOut = new java.io.FileOutputStream(entryDest.toString)
34+
val fileOut = Files.newOutputStream(entryDest.toNIO)
3335
IO.stream(zipStream, fileOut)
3436
fileOut.close()
3537
}

main/api/src/mill/api/JarOps.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package mill.api
22

3-
import mill.api.Loose.Agg
4-
5-
import java.io.{BufferedOutputStream, FileOutputStream}
3+
import java.io.BufferedOutputStream
4+
import java.nio.file.Files
65
import java.util.jar.{JarEntry, JarOutputStream, Manifest}
76
import scala.collection.mutable
7+
import mill.api.Loose.Agg
88

99
@experimental
1010
trait JarOps {
@@ -76,7 +76,7 @@ trait JarOps {
7676
val _ = seen.add(os.sub / "META-INF/MANIFEST.MF")
7777

7878
val jarStream = new JarOutputStream(
79-
new BufferedOutputStream(new FileOutputStream(jar.toIO)),
79+
new BufferedOutputStream(Files.newOutputStream(jar.toNIO)),
8080
manifest
8181
)
8282

main/client/src/mill/main/client/ServerLauncher.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import org.newsclub.net.unix.AFUNIXSocketAddress;
99

1010
import java.io.File;
11-
import java.io.FileOutputStream;
1211
import java.io.InputStream;
1312
import java.io.OutputStream;
1413
import java.io.PrintStream;
@@ -126,7 +125,8 @@ int run(Path serverDir, boolean setJnaNoSys, Locks locks) throws Exception {
126125
) {
127126
stdoutTailer.start();
128127
stderrTailer.start();
129-
try (FileOutputStream f = new FileOutputStream(serverDir + "/" + ServerFiles.runArgs)) {
128+
String serverPath = serverDir + "/" + ServerFiles.runArgs;
129+
try (OutputStream f = Files.newOutputStream(Paths.get(serverPath))) {
130130
f.write(System.console() != null ? 1 : 0);
131131
Util.writeString(f, BuildInfo.millVersion);
132132
Util.writeArgs(args, f);

main/client/test/src/mill/main/client/FileToStreamTailerTest.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33

44
import java.io.ByteArrayOutputStream;
55
import java.io.File;
6-
import java.io.FileOutputStream;
76
import java.io.PrintStream;
8-
7+
import java.nio.file.Files;
98
import org.junit.Ignore;
109
import org.junit.Test;
1110

@@ -49,7 +48,7 @@ public void handleNoExistingFileThatAppearsLater() throws Exception {
4948
assertEquals(bas.toString(), "");
5049

5150
try (
52-
PrintStream out = new PrintStream(new FileOutputStream(file));
51+
PrintStream out = new PrintStream(Files.newOutputStream(file.toPath()));
5352
) {
5453
out.println("log line");
5554
assertTrue(file.exists());
@@ -76,7 +75,7 @@ public void handleExistingInitiallyEmptyFile() throws Exception{
7675
assertEquals(bas.toString(), "");
7776

7877
try (
79-
PrintStream out = new PrintStream(new FileOutputStream(file));
78+
PrintStream out = new PrintStream(Files.newOutputStream(file.toPath()));
8079
) {
8180
out.println("log line");
8281
assertTrue(file.exists());
@@ -95,7 +94,7 @@ public void handleExistingFileWithOldContent() throws Exception{
9594
assertTrue(file.exists());
9695

9796
try (
98-
PrintStream out = new PrintStream(new FileOutputStream(file));
97+
PrintStream out = new PrintStream(Files.newOutputStream(file.toPath()));
9998
) {
10099
out.println("old line 1");
101100
out.println("old line 2");
@@ -130,7 +129,7 @@ public void handleExistingEmptyFileWhichDisappearsAndComesBack() throws Exceptio
130129
assertEquals(bas.toString(), "");
131130

132131
try (
133-
PrintStream out = new PrintStream(new FileOutputStream(file));
132+
PrintStream out = new PrintStream(Files.newOutputStream(file.toPath()));
134133
) {
135134
out.println("log line 1");
136135
out.println("log line 2");
@@ -146,7 +145,7 @@ public void handleExistingEmptyFileWhichDisappearsAndComesBack() throws Exceptio
146145
Thread.sleep(100);
147146

148147
try (
149-
PrintStream out = new PrintStream(new FileOutputStream(file));
148+
PrintStream out = new PrintStream(Files.newOutputStream(file.toPath()));
150149
) {
151150
out.println("new line");
152151
assertTrue(file.exists());

main/util/src/mill/util/Util.scala

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package mill.util
22

3+
import java.nio.file.Files
4+
import java.nio.file.Paths
35
import coursier.Repository
46
import mill.api.Loose.Agg
57
import mill.api.{BuildInfo, Ctx, IO, PathRef, Result}
@@ -19,7 +21,7 @@ object Util {
1921
{
2022
val millOptionsPath = sys.props("MILL_OPTIONS_PATH")
2123
if (millOptionsPath != null)
22-
LongMillProps.load(new java.io.FileInputStream(millOptionsPath))
24+
LongMillProps.load(Files.newInputStream(Paths.get(millOptionsPath)))
2325
}
2426

2527
def cleanupScaladoc(v: String): Array[String] = {
@@ -45,19 +47,13 @@ object Util {
4547
ctx: Ctx.Dest
4648
): PathRef = {
4749
val out = ctx.dest / dest
48-
4950
val website = new java.net.URI(url).toURL
50-
val rbc = java.nio.channels.Channels.newChannel(website.openStream)
51+
val websiteInputStream = website.openStream
5152
try {
52-
val fos = new java.io.FileOutputStream(out.toIO)
53-
try {
54-
fos.getChannel.transferFrom(rbc, 0, java.lang.Long.MAX_VALUE)
55-
PathRef(out)
56-
} finally {
57-
fos.close()
58-
}
53+
Files.copy(websiteInputStream, out.toNIO)
54+
PathRef(out)
5955
} finally {
60-
rbc.close()
56+
websiteInputStream.close()
6157
}
6258
}
6359

runner/client/src/mill/runner/client/MillProcessLauncher.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import static mill.main.client.OutFiles.*;
44

55
import java.io.File;
6-
import java.io.FileInputStream;
6+
import java.io.InputStream;
77
import java.io.IOException;
88
import java.nio.file.Files;
99
import java.nio.file.Path;
@@ -145,7 +145,7 @@ static String[] millClasspath() throws Exception {
145145

146146
// read MILL_CLASSPATH from file MILL_OPTIONS_PATH
147147
Properties millProps = new Properties();
148-
try (FileInputStream is = new FileInputStream(millOptionsPath)) {
148+
try (InputStream is = Files.newInputStream(Paths.get(millOptionsPath))) {
149149
millProps.load(is);
150150
} catch (IOException e) {
151151
throw new RuntimeException("Could not load '" + millOptionsPath + "'", e);

runner/src/mill/runner/MillMain.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package mill.runner
22

3-
import java.io.{FileOutputStream, PipedInputStream, PrintStream}
3+
import java.io.{PipedInputStream, PrintStream}
4+
import java.nio.file.Files
5+
import java.nio.file.StandardOpenOption
46
import java.util.Locale
57
import scala.jdk.CollectionConverters._
68
import scala.util.Properties
@@ -45,7 +47,8 @@ object MillMain {
4547
// and all Mill output (stdout and stderr) goes to a dedicated file
4648
val stderrFile = WorkspaceRoot.workspaceRoot / ".bsp/mill-bsp.stderr"
4749
os.makeDir.all(stderrFile / os.up)
48-
val errFile = new PrintStream(new FileOutputStream(stderrFile.toIO, true))
50+
val errFile =
51+
new PrintStream(Files.newOutputStream(stderrFile.toNIO, StandardOpenOption.APPEND))
4952
val errTee = new TeePrintStream(initialSystemStreams.err, errFile)
5053
val msg = s"Mill in BSP mode, version ${BuildInfo.millVersion}, ${new java.util.Date()}"
5154
errTee.println(msg)

testrunner/src/mill/testrunner/TestRunnerUtils.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import mill.api.{Ctx, Loose, TestReporter, internal}
44
import os.Path
55
import sbt.testing._
66

7-
import java.io.FileInputStream
7+
import java.nio.file.Files
88
import java.lang.annotation.Annotation
99
import java.lang.reflect.Modifier
1010
import java.util.concurrent.ConcurrentLinkedQueue
@@ -19,7 +19,7 @@ import scala.jdk.CollectionConverters.IteratorHasAsScala
1919
if (os.isDir(base)) {
2020
os.walk.stream(base).filter(_.ext == "class").map(_.relativeTo(base).toString)
2121
} else {
22-
val zip = new ZipInputStream(new FileInputStream(base.toIO))
22+
val zip = new ZipInputStream(Files.newInputStream(base.toNIO))
2323
geny.Generator.selfClosing(
2424
(
2525
Iterator.continually(zip.getNextEntry)

0 commit comments

Comments
 (0)