| author | matichuk <daniel.matichuk@nicta.com.au> | 
| Mon, 30 May 2016 16:11:53 +1000 | |
| changeset 63185 | 08369e33c185 | 
| parent 62854 | d8cf59edf819 | 
| child 64000 | 445b3deced8f | 
| permissions | -rw-r--r-- | 
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 1 | /* Title: Pure/General/file.scala | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 2 | Author: Makarius | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 3 | |
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 4 | File system operations. | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 5 | */ | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 6 | |
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 7 | package isabelle | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 8 | |
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 9 | |
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 10 | import java.io.{BufferedWriter, OutputStreamWriter, FileOutputStream, BufferedOutputStream,
 | 
| 51504 | 11 | OutputStream, InputStream, FileInputStream, BufferedInputStream, BufferedReader, | 
| 12 | InputStreamReader, File => JFile, IOException} | |
| 62703 | 13 | import java.nio.file.{StandardOpenOption, StandardCopyOption, Path => JPath,
 | 
| 14 | Files, SimpleFileVisitor, FileVisitResult} | |
| 62443 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 15 | import java.nio.file.attribute.BasicFileAttributes | 
| 60992 | 16 | import java.net.{URL, URLDecoder, MalformedURLException}
 | 
| 50684 
12b7e0b4a66e
support File.read_gzip as well, in accordance to File.write_gzip;
 wenzelm parents: 
50203diff
changeset | 17 | import java.util.zip.{GZIPInputStream, GZIPOutputStream}
 | 
| 60992 | 18 | import java.util.regex.Pattern | 
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 19 | |
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 20 | import scala.collection.mutable | 
| 60992 | 21 | import scala.util.matching.Regex | 
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 22 | |
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 23 | |
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 24 | object File | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 25 | {
 | 
| 60992 | 26 | /* standard path (Cygwin or Posix) */ | 
| 60988 | 27 | |
| 28 | def standard_path(path: Path): String = path.expand.implode | |
| 29 | ||
| 60992 | 30 | def standard_path(platform_path: String): String = | 
| 31 |     if (Platform.is_windows) {
 | |
| 32 |       val Platform_Root = new Regex("(?i)" +
 | |
| 61291 | 33 | Pattern.quote(Isabelle_System.cygwin_root()) + """(?:\\+|\z)(.*)""") | 
| 60992 | 34 |       val Drive = new Regex("""([a-zA-Z]):\\*(.*)""")
 | 
| 35 | ||
| 36 |       platform_path.replace('/', '\\') match {
 | |
| 37 |         case Platform_Root(rest) => "/" + rest.replace('\\', '/')
 | |
| 38 | case Drive(letter, rest) => | |
| 39 | "/cygdrive/" + Word.lowercase(letter) + | |
| 40 |             (if (rest == "") "" else "/" + rest.replace('\\', '/'))
 | |
| 41 |         case path => path.replace('\\', '/')
 | |
| 42 | } | |
| 43 | } | |
| 44 | else platform_path | |
| 45 | ||
| 46 | def standard_path(file: JFile): String = standard_path(file.getPath) | |
| 47 | ||
| 48 | def standard_url(name: String): String = | |
| 49 |     try {
 | |
| 50 | val url = new URL(name) | |
| 51 | if (url.getProtocol == "file") | |
| 52 | standard_path(URLDecoder.decode(url.getPath, UTF8.charset_name)) | |
| 53 | else name | |
| 54 | } | |
| 55 |     catch { case _: MalformedURLException => standard_path(name) }
 | |
| 56 | ||
| 57 | ||
| 58 | /* platform path (Windows or Posix) */ | |
| 59 | ||
| 60 |   private val Cygdrive = new Regex("/cygdrive/([a-zA-Z])($|/.*)")
 | |
| 61 |   private val Named_Root = new Regex("//+([^/]*)(.*)")
 | |
| 62 | ||
| 63 | def platform_path(standard_path: String): String = | |
| 64 |     if (Platform.is_windows) {
 | |
| 65 | val result_path = new StringBuilder | |
| 66 | val rest = | |
| 67 |         standard_path match {
 | |
| 68 | case Cygdrive(drive, rest) => | |
| 69 | result_path ++= (Word.uppercase(drive) + ":" + JFile.separator) | |
| 70 | rest | |
| 71 | case Named_Root(root, rest) => | |
| 72 | result_path ++= JFile.separator | |
| 73 | result_path ++= JFile.separator | |
| 74 | result_path ++= root | |
| 75 | rest | |
| 76 |           case path if path.startsWith("/") =>
 | |
| 61291 | 77 | result_path ++= Isabelle_System.cygwin_root() | 
| 60992 | 78 | path | 
| 79 | case path => path | |
| 80 | } | |
| 81 |       for (p <- space_explode('/', rest) if p != "") {
 | |
| 82 | val len = result_path.length | |
| 83 | if (len > 0 && result_path(len - 1) != JFile.separatorChar) | |
| 84 | result_path += JFile.separatorChar | |
| 85 | result_path ++= p | |
| 86 | } | |
| 87 | result_path.toString | |
| 88 | } | |
| 89 | else standard_path | |
| 90 | ||
| 91 | def platform_path(path: Path): String = platform_path(standard_path(path)) | |
| 60988 | 92 | def platform_file(path: Path): JFile = new JFile(platform_path(path)) | 
| 93 | ||
| 60992 | 94 | def platform_url(raw_path: Path): String = | 
| 60988 | 95 |   {
 | 
| 96 | val path = raw_path.expand | |
| 97 | require(path.is_absolute) | |
| 98 |     val s = platform_path(path).replaceAll(" ", "%20")
 | |
| 99 | if (!Platform.is_windows) "file://" + s | |
| 100 |     else if (s.startsWith("\\\\")) "file:" + s.replace('\\', '/')
 | |
| 101 |     else "file:///" + s.replace('\\', '/')
 | |
| 102 | } | |
| 103 | ||
| 60992 | 104 | |
| 62545 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 105 | /* bash path */ | 
| 60992 | 106 | |
| 62548 | 107 | private def bash_chr(c: Byte): String = | 
| 62545 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 108 |   {
 | 
| 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 109 | val ch = c.toChar | 
| 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 110 |     ch match {
 | 
| 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 111 | case '\t' => "$'\\t'" | 
| 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 112 | case '\n' => "$'\\n'" | 
| 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 113 | case '\f' => "$'\\f'" | 
| 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 114 | case '\r' => "$'\\r'" | 
| 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 115 | case _ => | 
| 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 116 | if (Symbol.is_ascii_letter(ch) || Symbol.is_ascii_digit(ch) || "-./:_".contains(ch)) | 
| 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 117 | Symbol.ascii(ch) | 
| 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 118 | else if (c < 0) "$'\\x" + Integer.toHexString(256 + c) + "'" | 
| 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 119 | else if (c < 16) "$'\\x0" + Integer.toHexString(c) + "'" | 
| 62548 | 120 | else if (c < 32 || c >= 127) "$'\\x" + Integer.toHexString(c) + "'" | 
| 62545 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 121 | else "\\" + ch | 
| 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 122 | } | 
| 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 123 | } | 
| 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 124 | |
| 62548 | 125 | def bash_string(s: String): String = | 
| 62854 | 126 | if (s == "") "\"\"" | 
| 127 | else UTF8.bytes(s).iterator.map(bash_chr(_)).mkString | |
| 62545 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 128 | |
| 62548 | 129 | def bash_args(args: List[String]): String = | 
| 130 |     args.iterator.map(bash_string(_)).mkString(" ")
 | |
| 62545 
8ebffdaf2ce2
Bash.process always uses a closed script instead of an open argument list, for extra robustness on Windows, where quoting is not well-defined;
 wenzelm parents: 
62544diff
changeset | 131 | |
| 62548 | 132 | def bash_path(path: Path): String = bash_string(standard_path(path)) | 
| 133 | def bash_path(file: JFile): String = bash_string(standard_path(file)) | |
| 60988 | 134 | |
| 135 | ||
| 62544 | 136 | /* directory entries */ | 
| 137 | ||
| 138 | def check_dir(path: Path): Path = | |
| 139 |     if (path.is_dir) path else error("No such directory: " + path)
 | |
| 140 | ||
| 141 | def check_file(path: Path): Path = | |
| 142 |     if (path.is_file) path else error("No such file: " + path)
 | |
| 143 | ||
| 144 | ||
| 62829 
4141c2a8458b
clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
 wenzelm parents: 
62704diff
changeset | 145 | /* directory content */ | 
| 
4141c2a8458b
clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
 wenzelm parents: 
62704diff
changeset | 146 | |
| 
4141c2a8458b
clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
 wenzelm parents: 
62704diff
changeset | 147 | def read_dir(dir: Path): List[String] = | 
| 
4141c2a8458b
clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
 wenzelm parents: 
62704diff
changeset | 148 |   {
 | 
| 
4141c2a8458b
clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
 wenzelm parents: 
62704diff
changeset | 149 |     if (!dir.is_dir) error("Bad directory: " + dir.toString)
 | 
| 
4141c2a8458b
clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
 wenzelm parents: 
62704diff
changeset | 150 | val files = dir.file.listFiles | 
| 
4141c2a8458b
clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
 wenzelm parents: 
62704diff
changeset | 151 | if (files == null) Nil | 
| 
4141c2a8458b
clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
 wenzelm parents: 
62704diff
changeset | 152 | else files.toList.map(_.getName) | 
| 
4141c2a8458b
clarified Isabelle tool wrapper: bash, Scala, no perl, no ML;
 wenzelm parents: 
62704diff
changeset | 153 | } | 
| 48613 
232652ac346e
clarified directory content operations (similar to ML version);
 wenzelm parents: 
48550diff
changeset | 154 | |
| 62443 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 155 | def find_files(start: JFile, pred: JFile => Boolean = _ => true): List[JFile] = | 
| 48613 
232652ac346e
clarified directory content operations (similar to ML version);
 wenzelm parents: 
48550diff
changeset | 156 |   {
 | 
| 62443 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 157 | val result = new mutable.ListBuffer[JFile] | 
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 158 | |
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 159 | if (start.isFile && pred(start)) result += start | 
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 160 |     else if (start.isDirectory) {
 | 
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 161 | Files.walkFileTree(start.toPath, | 
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 162 |         new SimpleFileVisitor[JPath] {
 | 
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 163 | override def visitFile(path: JPath, attrs: BasicFileAttributes): FileVisitResult = | 
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 164 |           {
 | 
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 165 | val file = path.toFile | 
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 166 | if (pred(file)) result += file | 
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 167 | FileVisitResult.CONTINUE | 
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 168 | } | 
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 169 | } | 
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 170 | ) | 
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 171 | } | 
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 172 | |
| 
133f65ac17e5
just one File.find_files, based on Java 7 Files operations;
 wenzelm parents: 
62294diff
changeset | 173 | result.toList | 
| 48613 
232652ac346e
clarified directory content operations (similar to ML version);
 wenzelm parents: 
48550diff
changeset | 174 | } | 
| 
232652ac346e
clarified directory content operations (similar to ML version);
 wenzelm parents: 
48550diff
changeset | 175 | |
| 
232652ac346e
clarified directory content operations (similar to ML version);
 wenzelm parents: 
48550diff
changeset | 176 | |
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 177 | /* read */ | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 178 | |
| 54440 | 179 | def read(file: JFile): String = Bytes.read(file).toString | 
| 48913 
f686cb016c0c
more direct File.read_bytes -- avoid cumulative copying of StringBuilder;
 wenzelm parents: 
48613diff
changeset | 180 | def read(path: Path): String = read(path.file) | 
| 
f686cb016c0c
more direct File.read_bytes -- avoid cumulative copying of StringBuilder;
 wenzelm parents: 
48613diff
changeset | 181 | |
| 50684 
12b7e0b4a66e
support File.read_gzip as well, in accordance to File.write_gzip;
 wenzelm parents: 
50203diff
changeset | 182 | |
| 
12b7e0b4a66e
support File.read_gzip as well, in accordance to File.write_gzip;
 wenzelm parents: 
50203diff
changeset | 183 | def read_stream(reader: BufferedReader): String = | 
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 184 |   {
 | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 185 | val output = new StringBuilder(100) | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 186 | var c = -1 | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 187 |     while ({ c = reader.read; c != -1 }) output += c.toChar
 | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 188 | reader.close | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 189 | output.toString | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 190 | } | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 191 | |
| 50684 
12b7e0b4a66e
support File.read_gzip as well, in accordance to File.write_gzip;
 wenzelm parents: 
50203diff
changeset | 192 | def read_stream(stream: InputStream): String = | 
| 
12b7e0b4a66e
support File.read_gzip as well, in accordance to File.write_gzip;
 wenzelm parents: 
50203diff
changeset | 193 | read_stream(new BufferedReader(new InputStreamReader(stream, UTF8.charset))) | 
| 
12b7e0b4a66e
support File.read_gzip as well, in accordance to File.write_gzip;
 wenzelm parents: 
50203diff
changeset | 194 | |
| 
12b7e0b4a66e
support File.read_gzip as well, in accordance to File.write_gzip;
 wenzelm parents: 
50203diff
changeset | 195 | def read_gzip(file: JFile): String = | 
| 
12b7e0b4a66e
support File.read_gzip as well, in accordance to File.write_gzip;
 wenzelm parents: 
50203diff
changeset | 196 | read_stream(new GZIPInputStream(new BufferedInputStream(new FileInputStream(file)))) | 
| 51504 | 197 | |
| 50684 
12b7e0b4a66e
support File.read_gzip as well, in accordance to File.write_gzip;
 wenzelm parents: 
50203diff
changeset | 198 | def read_gzip(path: Path): String = read_gzip(path.file) | 
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 199 | |
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 200 | |
| 50845 | 201 | /* read lines */ | 
| 202 | ||
| 203 | def read_lines(reader: BufferedReader, progress: String => Unit): List[String] = | |
| 204 |   {
 | |
| 205 | val result = new mutable.ListBuffer[String] | |
| 206 | var line: String = null | |
| 51251 
d55cce4d72dd
more permissive File.read_lines, which is relevant for Managed_Process join/kill;
 wenzelm parents: 
50845diff
changeset | 207 |     while ({ line = try { reader.readLine} catch { case _: IOException => null }; line != null }) {
 | 
| 50845 | 208 | progress(line) | 
| 209 | result += line | |
| 210 | } | |
| 211 | reader.close | |
| 212 | result.toList | |
| 213 | } | |
| 214 | ||
| 215 | ||
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 216 | /* write */ | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 217 | |
| 52671 
9a360530eac8
separate module XZ_File to avoid initial dependency on org.tukaani.xz;
 wenzelm parents: 
51982diff
changeset | 218 | def write_file(file: JFile, text: Iterable[CharSequence], | 
| 51982 | 219 | make_stream: OutputStream => OutputStream) | 
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 220 |   {
 | 
| 51504 | 221 | val stream = make_stream(new FileOutputStream(file)) | 
| 222 | val writer = new BufferedWriter(new OutputStreamWriter(stream, UTF8.charset)) | |
| 51982 | 223 |     try { text.iterator.foreach(writer.append(_)) }
 | 
| 224 |     finally { writer.close }
 | |
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 225 | } | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 226 | |
| 51982 | 227 | def write(file: JFile, text: Iterable[CharSequence]): Unit = write_file(file, text, (s) => s) | 
| 228 | def write(file: JFile, text: CharSequence): Unit = write(file, List(text)) | |
| 229 | def write(path: Path, text: Iterable[CharSequence]): Unit = write(path.file, text) | |
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 230 | def write(path: Path, text: CharSequence): Unit = write(path.file, text) | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 231 | |
| 51982 | 232 | def write_gzip(file: JFile, text: Iterable[CharSequence]): Unit = | 
| 51504 | 233 | write_file(file, text, (s: OutputStream) => new GZIPOutputStream(new BufferedOutputStream(s))) | 
| 51982 | 234 | def write_gzip(file: JFile, text: CharSequence): Unit = write_gzip(file, List(text)) | 
| 235 | def write_gzip(path: Path, text: Iterable[CharSequence]): Unit = write_gzip(path.file, text) | |
| 48494 | 236 | def write_gzip(path: Path, text: CharSequence): Unit = write_gzip(path.file, text) | 
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 237 | |
| 53336 | 238 | def write_backup(path: Path, text: CharSequence) | 
| 239 |   {
 | |
| 240 | path.file renameTo path.backup.file | |
| 62444 | 241 | write(path, text) | 
| 53336 | 242 | } | 
| 243 | ||
| 58610 | 244 | def write_backup2(path: Path, text: CharSequence) | 
| 245 |   {
 | |
| 246 | path.file renameTo path.backup2.file | |
| 62444 | 247 | write(path, text) | 
| 58610 | 248 | } | 
| 249 | ||
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 250 | |
| 62703 | 251 | /* append */ | 
| 252 | ||
| 253 | def append(file: JFile, text: CharSequence): Unit = | |
| 254 | Files.write(file.toPath, UTF8.bytes(text.toString), | |
| 255 | StandardOpenOption.APPEND, StandardOpenOption.CREATE) | |
| 256 | ||
| 257 | def append(path: Path, text: CharSequence): Unit = append(path.file, text) | |
| 258 | ||
| 259 | ||
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 260 | /* copy */ | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 261 | |
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 262 | def eq(file1: JFile, file2: JFile): Boolean = | 
| 49673 
2a088cff1e7b
more robust File.eq, and thus File.copy of "~~/lib/logo/isabelle.gif";
 wenzelm parents: 
49610diff
changeset | 263 |     try { java.nio.file.Files.isSameFile(file1.toPath, file2.toPath) }
 | 
| 
2a088cff1e7b
more robust File.eq, and thus File.copy of "~~/lib/logo/isabelle.gif";
 wenzelm parents: 
49610diff
changeset | 264 |     catch { case ERROR(_) => false }
 | 
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 265 | |
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 266 | def copy(src: JFile, dst: JFile) | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 267 |   {
 | 
| 61371 
17944b500166
clarified, according to Isabelle_System.copy_file in ML;
 wenzelm parents: 
61291diff
changeset | 268 | val target = if (dst.isDirectory) new JFile(dst, src.getName) else dst | 
| 61373 | 269 | if (!eq(src, target)) | 
| 270 | Files.copy(src.toPath, target.toPath, | |
| 271 | StandardCopyOption.COPY_ATTRIBUTES, | |
| 272 | StandardCopyOption.REPLACE_EXISTING) | |
| 48411 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 273 | } | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 274 | |
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 275 | def copy(path1: Path, path2: Path): Unit = copy(path1.file, path2.file) | 
| 
5b3440850d36
more abstract file system operations in Scala, corresponding to ML version;
 wenzelm parents: diff
changeset | 276 | } |