OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [java/] [io/] [File.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* File.java -- Class representing a file on disk
2
   Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GNU Classpath.
6
 
7
GNU Classpath is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
10
any later version.
11
 
12
GNU Classpath is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GNU Classpath; see the file COPYING.  If not, write to the
19
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301 USA.
21
 
22
Linking this library statically or dynamically with other modules is
23
making a combined work based on this library.  Thus, the terms and
24
conditions of the GNU General Public License cover the whole
25
combination.
26
 
27
As a special exception, the copyright holders of this library give you
28
permission to link this library with independent modules to produce an
29
executable, regardless of the license terms of these independent
30
modules, and to copy and distribute the resulting executable under
31
terms of your choice, provided that you also meet, for each linked
32
independent module, the terms and conditions of the license of that
33
module.  An independent module is a module which is not derived from
34
or based on this library.  If you modify this library, you may extend
35
this exception to your version of the library, but you are not
36
obligated to do so.  If you do not wish to do so, delete this
37
exception statement from your version. */
38
 
39
 
40
package java.io;
41
 
42
import gnu.classpath.SystemProperties;
43
 
44
import java.net.MalformedURLException;
45
import java.net.URI;
46
import java.net.URISyntaxException;
47
import java.net.URL;
48
 
49
/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
50
 * "The Java Language Specification", ISBN 0-201-63451-1
51
 * Status:  Complete to version 1.3.
52
 */
53
 
54
/**
55
 * This class represents a file or directory on a local disk.  It provides
56
 * facilities for dealing with a variety of systems that use various
57
 * types of path separators ("/" versus "\", for example).  It also
58
 * contains method useful for creating and deleting files and directories.
59
 *
60
 * @author Aaron M. Renn (arenn@urbanophile.com)
61
 * @author Tom Tromey (tromey@cygnus.com)
62
 */
63
public class File implements Serializable, Comparable
64
{
65
  private static final long serialVersionUID = 301077366599181567L;
66
 
67
  /**
68
   * This is the path separator string for the current host. This field
69
   * contains the value of the <code>file.separator</code> system property.
70
   * An example separator string would be "/" on the GNU system.
71
   */
72
  public static final String separator = SystemProperties.getProperty("file.separator");
73
  private static final String dupSeparator = separator + separator;
74
 
75
  /**
76
   * This is the first character of the file separator string.  On many
77
   * hosts (for example, on the GNU system), this represents the entire
78
   * separator string.  The complete separator string is obtained from the
79
   * <code>file.separator</code>system property.
80
   */
81
  public static final char separatorChar = separator.charAt(0);
82
 
83
  /**
84
   * This is the string that is used to separate the host name from the
85
   * path name in paths than include the host name.  It is the value of
86
   * the <code>path.separator</code> system property.
87
   */
88
  public static final String pathSeparator
89
    = SystemProperties.getProperty("path.separator");
90
 
91
  /**
92
   * This is the first character of the string used to separate the host name
93
   * from the path name in paths that include a host.  The separator string
94
   * is taken from the <code>path.separator</code> system property.
95
   */
96
  public static final char pathSeparatorChar = pathSeparator.charAt(0);
97
 
98
  /**
99
   * This is the path to the file set when the object is created.  It
100
   * may be an absolute or relative path name.
101
   */
102
  private String path;
103
 
104
 
105
  /**
106
   * The time (millisecond), when the last temporary file was created.
107
   */
108
  private static long last_tmp;
109
 
110
  /**
111
   * The number of files, created during the current millisecond.
112
   */
113
  private static int n_created;
114
 
115
  /**
116
   * This method tests whether or not the current thread is allowed to
117
   * to read the file pointed to by this object.  This will be true if and
118
   * and only if 1) the file exists and 2) the <code>SecurityManager</code>
119
   * (if any) allows access to the file via it's <code>checkRead</code>
120
   * method 3) the file is readable.
121
   *
122
   * @return <code>true</code> if reading is allowed,
123
   * <code>false</code> otherwise
124
   *
125
   * @exception SecurityException If the <code>SecurityManager</code>
126
   * does not allow access to the file
127
   */
128
  public boolean canRead()
129
  {
130
    // Test for existence. This also does the SecurityManager check
131
    if (!exists())
132
      return false;
133
 
134
    return VMFile.canRead(path);
135
  }
136
 
137
  /**
138
   * This method test whether or not the current thread is allowed to
139
   * write to this object.  This will be true if and only if 1) The
140
   * <code>SecurityManager</code> (if any) allows write access to the
141
   * file and 2) The file exists and 3) The file is writable.  To determine
142
   * whether or not a non-existent file can be created, check the parent
143
   * directory for write access.
144
   *
145
   * @return <code>true</code> if writing is allowed, <code>false</code>
146
   * otherwise
147
   *
148
   * @exception SecurityException If the <code>SecurityManager</code>
149
   * does not allow access to the file
150
   */
151
  public boolean canWrite()
152
  {
153
    // First do a SecurityCheck before doing anything else.
154
    checkWrite();
155
 
156
    // Test for existence.  This is required by the spec
157
    if (! VMFile.exists(path))
158
      return false;
159
 
160
    if (VMFile.isDirectory(path))
161
      return VMFile.canWriteDirectory(this);
162
    else
163
      return VMFile.canWrite(path);
164
  }
165
 
166
  /**
167
   * This method creates a new file of zero length with the same name as
168
   * the path of this <code>File</code> object if an only if that file
169
   * does not already exist.
170
   * <p>
171
   * A <code>SecurityManager.checkWrite</code> check is done prior
172
   * to performing this action.
173
   *
174
   * @return <code>true</code> if the file was created, <code>false</code> if
175
   * the file alread existed.
176
   *
177
   * @exception IOException If an I/O error occurs
178
   * @exception SecurityException If the <code>SecurityManager</code> will
179
   * not allow this operation to be performed.
180
   *
181
   * @since 1.2
182
   */
183
  public boolean createNewFile() throws IOException
184
  {
185
    checkWrite();
186
    return VMFile.create(path);
187
  }
188
  /**
189
   * This method deletes the file represented by this object.  If this file
190
   * is a directory, it must be empty in order for the delete to succeed.
191
   *
192
   * @return <code>true</code> if the file was deleted, <code>false</code>
193
   * otherwise
194
   *
195
   * @exception SecurityException If deleting of the file is not allowed
196
   */
197
  public synchronized boolean delete()
198
  {
199
    SecurityManager s = System.getSecurityManager();
200
 
201
    if (s != null)
202
      s.checkDelete(path);
203
 
204
    return VMFile.delete(path);
205
  }
206
 
207
  /**
208
   * This method tests two <code>File</code> objects for equality by
209
   * comparing the path of the specified <code>File</code> against the path
210
   * of this object.  The two objects are equal if an only if 1) The
211
   * argument is not null 2) The argument is a <code>File</code> object and
212
   * 3) The path of the <code>File</code>argument is equal to the path
213
   * of this object.
214
   * <p>
215
   * The paths of the files are determined by calling the
216
   * <code>getPath()</code>
217
   * method on each object.
218
   *
219
   * @return <code>true</code> if the two objects are equal,
220
   * <code>false</code> otherwise.
221
   */
222
  public boolean equals(Object obj)
223
  {
224
    if (! (obj instanceof File))
225
      return false;
226
 
227
    File other = (File) obj;
228
 
229
    if (VMFile.IS_CASE_SENSITIVE)
230
      return path.equals(other.path);
231
    else
232
      return path.equalsIgnoreCase(other.path);
233
  }
234
 
235
  /**
236
   * This method tests whether or not the file represented by the object
237
   * actually exists on the filesystem.
238
   *
239
   * @return <code>true</code> if the file exists, <code>false</code>otherwise.
240
   *
241
   * @exception SecurityException If reading of the file is not permitted
242
   */
243
  public boolean exists()
244
  {
245
    checkRead();
246
    return VMFile.exists(path);
247
  }
248
 
249
  /**
250
   * This method initializes a new <code>File</code> object to represent
251
   * a file with the specified path.
252
   *
253
   * @param name The path name of the file
254
   */
255
  public File(String name)
256
  {
257
    path = normalizePath (name);
258
  }
259
 
260
  // Remove duplicate and redundant separator characters.
261
  private String normalizePath(String p)
262
  {
263
    // On Windows, convert any '/' to '\'.  This appears to be the same logic
264
    // that Sun's Win32 Java performs.
265
    if (separatorChar == '\\')
266
      {
267
        p = p.replace ('/', '\\');
268
        // We have to special case the "\c:" prefix.
269
        if (p.length() > 2 && p.charAt(0) == '\\' &&
270
            ((p.charAt(1) >= 'a' && p.charAt(1) <= 'z') ||
271
            (p.charAt(1) >= 'A' && p.charAt(1) <= 'Z')) &&
272
            p.charAt(2) == ':')
273
          p = p.substring(1);
274
      }
275
 
276
    int dupIndex = p.indexOf(dupSeparator);
277
    int plen = p.length();
278
 
279
    // Special case: permit Windows UNC path prefix.
280
    if (dupSeparator.equals("\\\\") && dupIndex == 0)
281
      dupIndex = p.indexOf(dupSeparator, 1);
282
 
283
    if (dupIndex == -1)
284
      {
285
        // Ignore trailing separator (though on Windows "a:\", for
286
        // example, is a valid and minimal path).
287
        if (plen > 1 && p.charAt (plen - 1) == separatorChar)
288
          {
289
            if (! (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':'))
290
              return p.substring (0, plen - 1);
291
          }
292
        else
293
          return p;
294
      }
295
 
296
    StringBuffer newpath = new StringBuffer(plen);
297
    int last = 0;
298
    while (dupIndex != -1)
299
      {
300
        newpath.append(p.substring(last, dupIndex));
301
        // Ignore the duplicate path characters.
302
        while (p.charAt(dupIndex) == separatorChar)
303
          {
304
            dupIndex++;
305
            if (dupIndex == plen)
306
              return newpath.toString();
307
          }
308
        newpath.append(separatorChar);
309
        last = dupIndex;
310
        dupIndex = p.indexOf(dupSeparator, last);
311
      }
312
 
313
    // Again, ignore possible trailing separator (except special cases
314
    // like "a:\" on Windows).
315
    int end;
316
    if (plen > 1 && p.charAt (plen - 1) == separatorChar)
317
    {
318
      if (separatorChar == '\\' && plen == 3 && p.charAt (1) == ':')
319
        end = plen;
320
      else
321
        end = plen - 1;
322
    }
323
    else
324
      end = plen;
325
    newpath.append(p.substring(last, end));
326
 
327
    return newpath.toString();
328
  }
329
 
330
  /**
331
   * This method initializes a new <code>File</code> object to represent
332
   * a file in the specified named directory.  The path name to the file
333
   * will be the directory name plus the separator string plus the file
334
   * name.  If the directory path name ends in the separator string, another
335
   * separator string will still be appended.
336
   *
337
   * @param dirPath The path to the directory the file resides in
338
   * @param name The name of the file
339
   */
340
  public File(String dirPath, String name)
341
  {
342
    if (name == null)
343
      throw new NullPointerException();
344
    if (dirPath != null)
345
      {
346
        if (dirPath.length() > 0)
347
          {
348
            // Try to be smart about the number of separator characters.
349
            if (dirPath.charAt(dirPath.length() - 1) == separatorChar
350
                || name.length() == 0)
351
              path = normalizePath(dirPath + name);
352
            else
353
              path = normalizePath(dirPath + separatorChar + name);
354
          }
355
        else
356
          {
357
            // If dirPath is empty, use a system dependant
358
            // default prefix.
359
            // Note that the leading separators in name have
360
            // to be chopped off, to prevent them forming
361
            // a UNC prefix on Windows.
362
            if (separatorChar == '\\' /* TODO use ON_WINDOWS */)
363
              {
364
                int skip = 0;
365
                while(name.length() > skip
366
                    && (name.charAt(skip) == separatorChar
367
                    || name.charAt(skip) == '/'))
368
                  {
369
                    skip++;
370
                  }
371
                name = name.substring(skip);
372
              }
373
            path = normalizePath(separatorChar + name);
374
          }
375
      }
376
    else
377
      path = normalizePath(name);
378
  }
379
 
380
  /**
381
   * This method initializes a new <code>File</code> object to represent
382
   * a file in the specified directory.  If the <code>directory</code>
383
   * argument is <code>null</code>, the file is assumed to be in the
384
   * current directory as specified by the <code>user.dir</code> system
385
   * property
386
   *
387
   * @param directory The directory this file resides in
388
   * @param name The name of the file
389
   */
390
  public File(File directory, String name)
391
  {
392
    this (directory == null ? null : directory.path, name);
393
  }
394
 
395
  /**
396
   * This method initializes a new <code>File</code> object to represent
397
   * a file corresponding to the specified <code>file:</code> protocol URI.
398
   *
399
   * @param uri The uri.
400
   */
401
  public File(URI uri)
402
  {
403
    if (uri == null)
404
        throw new NullPointerException("uri is null");
405
 
406
    if (!uri.getScheme().equals("file"))
407
        throw new IllegalArgumentException("invalid uri protocol");
408
 
409
    path = normalizePath(uri.getPath());
410
  }
411
 
412
  /**
413
   * This method returns the path of this file as an absolute path name.
414
   * If the path name is already absolute, then it is returned.  Otherwise
415
   * the value returned is the current directory plus the separatory
416
   * string plus the path of the file.  The current directory is determined
417
   * from the <code>user.dir</code> system property.
418
   *
419
   * @return The absolute path of this file
420
   */
421
  public String getAbsolutePath()
422
  {
423
    if (isAbsolute())
424
      return path;
425
    else if (separatorChar == '\\'
426
             && path.length() > 0 && path.charAt (0) == '\\')
427
      {
428
        // On Windows, even if the path starts with a '\\' it is not
429
        // really absolute until we prefix the drive specifier from
430
        // the current working directory to it.
431
        return System.getProperty ("user.dir").substring (0, 2) + path;
432
      }
433
    else if (separatorChar == '\\'
434
             && path.length() > 1 && path.charAt (1) == ':'
435
             && ((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
436
                 || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z')))
437
      {
438
        // On Windows, a process has a current working directory for
439
        // each drive and a path like "G:foo\bar" would mean the 
440
        // absolute path "G:\wombat\foo\bar" if "\wombat" is the 
441
        // working directory on the G drive.
442
        String drvDir = null;
443
        try
444
          {
445
            drvDir = new File (path.substring (0, 2)).getCanonicalPath();
446
          }
447
        catch (IOException e)
448
          {
449
            drvDir = path.substring (0, 2) + "\\";
450
          }
451
 
452
        // Note: this would return "C:\\." for the path "C:.", if "\"
453
        // is the working folder on the C drive, but this is 
454
        // consistent with what Sun's JRE 1.4.1.01 actually returns!
455
        if (path.length() > 2)
456
          return drvDir + '\\' + path.substring (2, path.length());
457
        else
458
          return drvDir;
459
      }
460
    else if (path.equals(""))
461
      return System.getProperty ("user.dir");
462
    else
463
      return System.getProperty ("user.dir") + separatorChar + path;
464
  }
465
 
466
  /**
467
   * This method returns a <code>File</code> object representing the
468
   * absolute path of this object.
469
   *
470
   * @return A <code>File</code> with the absolute path of the object.
471
   *
472
   * @since 1.2
473
   */
474
  public File getAbsoluteFile()
475
  {
476
    return new File(getAbsolutePath());
477
  }
478
 
479
  /**
480
   * This method returns a canonical representation of the pathname of
481
   * this file.  The actual form of the canonical representation is
482
   * different.  On the GNU system, the canonical form differs from the
483
   * absolute form in that all relative file references to "." and ".."
484
   * are resolved and removed.
485
   * <p>
486
   * Note that this method, unlike the other methods which return path
487
   * names, can throw an IOException.  This is because native method
488
   * might be required in order to resolve the canonical path
489
   *
490
   * @exception IOException If an error occurs
491
   */
492
  public String getCanonicalPath() throws IOException
493
  {
494
    // On Windows, getAbsolutePath might end up calling us, so we
495
    // have to special case that call to avoid infinite recursion.
496
    if (separatorChar == '\\' && path.length() == 2 &&
497
        ((path.charAt(0) >= 'a' && path.charAt(0) <= 'z') ||
498
         (path.charAt(0) >= 'A' && path.charAt(0) <= 'Z')) &&
499
        path.charAt(1) == ':')
500
    {
501
        return VMFile.toCanonicalForm(path);
502
    }
503
    // Call getAbsolutePath first to make sure that we do the
504
    // current directory handling, because the native code
505
    // may have a different idea of the current directory.
506
    return VMFile.toCanonicalForm(getAbsolutePath());
507
  }
508
 
509
  /**
510
   * This method returns a <code>File</code> object representing the
511
   * canonical path of this object.
512
   *
513
   * @return A <code>File</code> instance representing the canonical path of
514
   * this object.
515
   *
516
   * @exception IOException If an error occurs.
517
   *
518
   * @since 1.2
519
   */
520
  public File getCanonicalFile() throws IOException
521
  {
522
    return new File(getCanonicalPath());
523
  }
524
 
525
  /**
526
   * This method returns the name of the file.  This is everything in the
527
   * complete path of the file after the last instance of the separator
528
   * string.
529
   *
530
   * @return The file name
531
   */
532
  public String getName()
533
  {
534
        return VMFile.getName(path);
535
  }
536
 
537
  /**
538
   * This method returns a <code>String</code> the represents this file's
539
   * parent.  <code>null</code> is returned if the file has no parent.  The
540
   * parent is determined via a simple operation which removes the
541
   *
542
   * @return The parent directory of this file
543
   */
544
  public String getParent()
545
  {
546
    String prefix = null;
547
    int nameSeqIndex = 0;
548
 
549
    if (path.equals(""))
550
      return null;
551
 
552
    // The "prefix", if present, is the leading "/" on UNIX and 
553
    // either the drive specifier (e.g. "C:") or the leading "\\"
554
    // of a UNC network path on Windows.
555
    if (separatorChar == '/' && path.charAt (0) == '/')
556
      {
557
        prefix = "/";
558
        nameSeqIndex = 1;
559
      }
560
    else if (separatorChar == '\\' && path.length() > 1)
561
      {
562
        if ((path.charAt (0) == '\\' && path.charAt (1) == '\\')
563
            || (((path.charAt (0) >= 'a' && path.charAt (0) <= 'z')
564
                 || (path.charAt (0) >= 'A' && path.charAt (0) <= 'Z'))
565
                && path.charAt (1) == ':'))
566
          {
567
            prefix = path.substring (0, 2);
568
            nameSeqIndex = 2;
569
          }
570
      }
571
 
572
    // According to the JDK docs, the returned parent path is the 
573
    // portion of the name sequence before the last separator
574
    // character, if found, prefixed by the prefix, otherwise null.
575
    if (nameSeqIndex < path.length())
576
      {
577
        String nameSeq = path.substring (nameSeqIndex, path.length());
578
        int last = nameSeq.lastIndexOf (separatorChar);
579
        if (last == -1)
580
          return prefix;
581
        else if (last == (nameSeq.length() - 1))
582
          // Note: The path would not have a trailing separator
583
          // except for cases like "C:\" on Windows (see 
584
          // normalizePath( )), where Sun's JRE 1.4 returns null.
585
          return null;
586
        else if (last == 0)
587
          last++;
588
 
589
        if (prefix != null)
590
          return prefix + nameSeq.substring (0, last);
591
        else
592
          return nameSeq.substring (0, last);
593
      }
594
    else
595
      // Sun's JRE 1.4 returns null if the prefix is the only 
596
      // component of the path - so "/" gives null on UNIX and 
597
      // "C:", "\\", etc. return null on Windows.
598
      return null;
599
  }
600
 
601
  /**
602
   * This method returns a <code>File</code> object representing the parent
603
   * file of this one.
604
   *
605
   * @return a <code>File</code> for the parent of this object.
606
   * <code>null</code>
607
   * will be returned if this object does not have a parent.
608
   *
609
   * @since 1.2
610
   */
611
  public File getParentFile()
612
  {
613
    String parent = getParent();
614
    return parent != null ? new File(parent) : null;
615
  }
616
 
617
  /**
618
   * Returns the path name that represents this file.  May be a relative
619
   * or an absolute path name
620
   *
621
   * @return The pathname of this file
622
   */
623
  public String getPath()
624
  {
625
    return path;
626
  }
627
 
628
  /**
629
   * This method returns a hash code representing this file.  It is the
630
   * hash code of the path of this file (as returned by <code>getPath()</code>)
631
   * exclusived or-ed with the value 1234321.
632
   *
633
   * @return The hash code for this object
634
   */
635
  public int hashCode()
636
  {
637
    if (VMFile.IS_CASE_SENSITIVE)
638
      return path.hashCode() ^ 1234321;
639
    else
640
      return path.toLowerCase().hashCode() ^ 1234321;
641
  }
642
 
643
  /**
644
   * This method returns true if this object represents an absolute file
645
   * path and false if it does not.  The definition of an absolute path varies
646
   * by system.  As an example, on GNU systems, a path is absolute if it starts
647
   * with a "/".
648
   *
649
   * @return <code>true</code> if this object represents an absolute
650
   * file name, <code>false</code> otherwise.
651
   */
652
  public boolean isAbsolute()
653
  {
654
    if (separatorChar == '\\')
655
        return path.startsWith(dupSeparator) ||
656
            (path.length() > 2 &&
657
             ((path.charAt(0) >= 'a' && path.charAt(0) <= 'z') ||
658
              (path.charAt(0) >= 'A' && path.charAt(0) <= 'Z')) &&
659
             path.charAt(1) == ':' &&
660
             path.charAt(2) == '\\');
661
    else
662
        return path.startsWith(separator);
663
  }
664
 
665
  /**
666
   * This method tests whether or not the file represented by this object
667
   * is a directory.  In order for this method to return <code>true</code>,
668
   * the file represented by this object must exist and be a directory.
669
   *
670
   * @return <code>true</code> if this file is a directory, <code>false</code>
671
   * otherwise
672
   *
673
   * @exception SecurityException If reading of the file is not permitted
674
   */
675
  public boolean isDirectory()
676
  {
677
    checkRead();
678
    return VMFile.isDirectory(path);
679
  }
680
 
681
  /**
682
   * This method tests whether or not the file represented by this object
683
   * is a "plain" file.  A file is a plain file if and only if it 1) Exists,
684
   * 2) Is not a directory or other type of special file.
685
   *
686
   * @return <code>true</code> if this is a plain file, <code>false</code>
687
   * otherwise
688
   *
689
   * @exception SecurityException If reading of the file is not permitted
690
   */
691
  public boolean isFile()
692
  {
693
    checkRead();
694
    return VMFile.isFile(path);
695
  }
696
 
697
  /**
698
   * This method tests whether or not this file represents a "hidden" file.
699
   * On GNU systems, a file is hidden if its name begins with a "."
700
   * character.  Files with these names are traditionally not shown with
701
   * directory listing tools.
702
   *
703
   * @return <code>true</code> if the file is hidden, <code>false</code>
704
   * otherwise.
705
   *
706
   * @since 1.2
707
   */
708
  public boolean isHidden()
709
  {
710
    return VMFile.isHidden(path);
711
  }
712
 
713
  /**
714
   * This method returns the last modification time of this file.  The
715
   * time value returned is an abstract value that should not be interpreted
716
   * as a specified time value.  It is only useful for comparing to other
717
   * such time values returned on the same system.  In that case, the larger
718
   * value indicates a more recent modification time.
719
   * <p>
720
   * If the file does not exist, then a value of 0 is returned.
721
   *
722
   * @return The last modification time of the file
723
   *
724
   * @exception SecurityException If reading of the file is not permitted
725
   */
726
  public long lastModified()
727
  {
728
    checkRead();
729
    return VMFile.lastModified(path);
730
  }
731
 
732
  /**
733
   * This method returns the length of the file represented by this object,
734
   * or 0 if the specified file does not exist.
735
   *
736
   * @return The length of the file
737
   *
738
   * @exception SecurityException If reading of the file is not permitted
739
   */
740
  public long length()
741
  {
742
    checkRead();
743
    return VMFile.length(path);
744
  }
745
 
746
  /**
747
   * This method returns a array of <code>String</code>'s representing the
748
   * list of files is then directory represented by this object.  If this
749
   * object represents a non-directory file or a non-existent file, then
750
   * <code>null</code> is returned.  The list of files will not contain
751
   * any names such as "." or ".." which indicate the current or parent
752
   * directory.  Also, the names are not guaranteed to be sorted.
753
   * <p>
754
   * In this form of the <code>list()</code> method, a filter is specified
755
   * that allows the caller to control which files are returned in the
756
   * list.  The <code>FilenameFilter</code> specified is called for each
757
   * file returned to determine whether or not that file should be included
758
   * in the list.
759
   * <p>
760
   * A <code>SecurityManager</code> check is made prior to reading the
761
   * directory.  If read access to the directory is denied, an exception
762
   * will be thrown.
763
   *
764
   * @param filter An object which will identify files to exclude from
765
   * the directory listing.
766
   *
767
   * @return An array of files in the directory, or <code>null</code>
768
   * if this object does not represent a valid directory.
769
   *
770
   * @exception SecurityException If read access is not allowed to the
771
   * directory by the <code>SecurityManager</code>
772
   */
773
  public String[] list(FilenameFilter filter)
774
  {
775
    checkRead();
776
 
777
    if (!exists() || !isDirectory())
778
      return null;
779
 
780
    // Get the list of files
781
    String files[] = VMFile.list(path);
782
 
783
    // Check if an error occured in listInternal().
784
    if (files == null)
785
      return null;
786
 
787
    if (filter == null)
788
      return files;
789
 
790
    // Apply the filter
791
    int count = 0;
792
    for (int i = 0; i < files.length; i++)
793
      {
794
        if (filter.accept(this, files[i]))
795
          ++count;
796
        else
797
          files[i] = null;
798
      }
799
 
800
    String[] retfiles = new String[count];
801
    count = 0;
802
    for (int i = 0; i < files.length; i++)
803
      if (files[i] != null)
804
        retfiles[count++] = files[i];
805
 
806
    return retfiles;
807
  }
808
 
809
  /**
810
   * This method returns a array of <code>String</code>'s representing the
811
   * list of files is then directory represented by this object.  If this
812
   * object represents a non-directory file or a non-existent file, then
813
   * <code>null</code> is returned.  The list of files will not contain
814
   * any names such as "." or ".." which indicate the current or parent
815
   * directory.  Also, the names are not guaranteed to be sorted.
816
   * <p>
817
   * A <code>SecurityManager</code> check is made prior to reading the
818
   * directory.  If read access to the directory is denied, an exception
819
   * will be thrown.
820
   *
821
   * @return An array of files in the directory, or <code>null</code> if
822
   * this object does not represent a valid directory.
823
   *
824
   * @exception SecurityException If read access is not allowed to the
825
   * directory by the <code>SecurityManager</code>
826
   */
827
  public String[] list()
828
  {
829
    return list(null);
830
  }
831
 
832
  /**
833
   * This method returns an array of <code>File</code> objects representing
834
   * all the files in the directory represented by this object. If this
835
   * object does not represent a directory, <code>null</code> is returned.
836
   * Each of the returned <code>File</code> object is constructed with this
837
   * object as its parent.
838
   * <p>
839
   * A <code>SecurityManager</code> check is made prior to reading the
840
   * directory.  If read access to the directory is denied, an exception
841
   * will be thrown.
842
   *
843
   * @return An array of <code>File</code> objects for this directory.
844
   *
845
   * @exception SecurityException If the <code>SecurityManager</code> denies
846
   * access to this directory.
847
   *
848
   * @since 1.2
849
   */
850
  public File[] listFiles()
851
  {
852
    return listFiles((FilenameFilter) null);
853
  }
854
 
855
  /**
856
   * This method returns an array of <code>File</code> objects representing
857
   * all the files in the directory represented by this object. If this
858
   * object does not represent a directory, <code>null</code> is returned.
859
   * Each of the returned <code>File</code> object is constructed with this
860
   * object as its parent.
861
   * <p>
862
   * In this form of the <code>listFiles()</code> method, a filter is specified
863
   * that allows the caller to control which files are returned in the
864
   * list.  The <code>FilenameFilter</code> specified is called for each
865
   * file returned to determine whether or not that file should be included
866
   * in the list.
867
   * <p>
868
   * A <code>SecurityManager</code> check is made prior to reading the
869
   * directory.  If read access to the directory is denied, an exception
870
   * will be thrown.
871
   *
872
   * @return An array of <code>File</code> objects for this directory.
873
   *
874
   * @exception SecurityException If the <code>SecurityManager</code> denies
875
   * access to this directory.
876
   *
877
   * @since 1.2
878
   */
879
  public File[] listFiles(FilenameFilter filter)
880
  {
881
    String[] filelist = list(filter);
882
 
883
    if (filelist == null)
884
      return null;
885
 
886
    File[] fobjlist = new File [filelist.length];
887
 
888
    for (int i = 0; i < filelist.length; i++)
889
      fobjlist [i] = new File(this, filelist [i]);
890
 
891
    return fobjlist;
892
  }
893
 
894
  /**
895
   * This method returns an array of <code>File</code> objects representing
896
   * all the files in the directory represented by this object. If this
897
   * object does not represent a directory, <code>null</code> is returned.
898
   * Each of the returned <code>File</code> object is constructed with this
899
   * object as its parent.
900
   * <p>
901
   * In this form of the <code>listFiles()</code> method, a filter is specified
902
   * that allows the caller to control which files are returned in the
903
   * list.  The <code>FileFilter</code> specified is called for each
904
   * file returned to determine whether or not that file should be included
905
   * in the list.
906
   * <p>
907
   * A <code>SecurityManager</code> check is made prior to reading the
908
   * directory.  If read access to the directory is denied, an exception
909
   * will be thrown.
910
   *
911
   * @return An array of <code>File</code> objects for this directory.
912
   *
913
   * @exception SecurityException If the <code>SecurityManager</code> denies
914
   * access to this directory.
915
   *
916
   * @since 1.2
917
   */
918
  public File[] listFiles(FileFilter filter)
919
  {
920
    File[] fobjlist = listFiles((FilenameFilter) null);
921
 
922
    if (fobjlist == null)
923
      return null;
924
 
925
    if (filter == null)
926
      return fobjlist;
927
 
928
    int count = 0;
929
    for (int i = 0; i < fobjlist.length; i++)
930
      if (filter.accept(fobjlist[i]) == true)
931
        ++count;
932
 
933
    File[] final_list = new File[count];
934
    count = 0;
935
    for (int i = 0; i < fobjlist.length; i++)
936
      if (filter.accept(fobjlist[i]) == true)
937
        {
938
          final_list[count] = fobjlist[i];
939
          ++count;
940
        }
941
 
942
    return final_list;
943
  }
944
 
945
  /**
946
   * This method returns a <code>String</code> that is the path name of the
947
   * file as returned by <code>getPath</code>.
948
   *
949
   * @return A <code>String</code> representation of this file
950
   */
951
  public String toString()
952
  {
953
    return path;
954
  }
955
 
956
  /**
957
   * @return A <code>URI</code> for this object.
958
   */
959
  public URI toURI()
960
  {
961
    String abspath = getAbsolutePath();
962
 
963
    if (isDirectory() || path.equals(""))
964
      abspath = abspath + separatorChar;
965
 
966
    if (separatorChar == '\\')
967
      abspath = separatorChar + abspath;
968
 
969
    try
970
      {
971
        return new URI("file", null, null, -1,
972
                       abspath.replace(separatorChar, '/'),
973
                       null, null);
974
      }
975
    catch (URISyntaxException use)
976
      {
977
        // Can't happen.
978
        throw (InternalError) new InternalError("Unconvertible file: "
979
                                                + this).initCause(use);
980
      }
981
  }
982
 
983
  /**
984
   * This method returns a <code>URL</code> with the <code>file:</code>
985
   * protocol that represents this file.  The exact form of this URL is
986
   * system dependent.
987
   *
988
   * @return A <code>URL</code> for this object.
989
   *
990
   * @exception MalformedURLException If the URL cannot be created
991
   * successfully.
992
   */
993
  public URL toURL() throws MalformedURLException
994
  {
995
    // On Win32, Sun's JDK returns URLs of the form "file:/c:/foo/bar.txt",
996
    // while on UNIX, it returns URLs of the form "file:/foo/bar.txt". 
997
    if (separatorChar == '\\')
998
      return new URL ("file:/" + getAbsolutePath().replace ('\\', '/')
999
                      + (isDirectory() ? "/" : ""));
1000
    else
1001
      return new URL ("file:" + getAbsolutePath()
1002
                      + (isDirectory() ? "/" : ""));
1003
  }
1004
 
1005
 
1006
  /**
1007
   * This method creates a directory for the path represented by this object.
1008
   *
1009
   * @return <code>true</code> if the directory was created,
1010
   * <code>false</code> otherwise
1011
   *
1012
   * @exception SecurityException If write access is not allowed to this file
1013
   */
1014
  public boolean mkdir()
1015
  {
1016
    checkWrite();
1017
    return VMFile.mkdir(path);
1018
  }
1019
 
1020
  /**
1021
   * This method creates a directory for the path represented by this file.
1022
   * It will also create any intervening parent directories if necessary.
1023
   *
1024
   * @return <code>true</code> if the directory was created,
1025
   * <code>false</code> otherwise
1026
   *
1027
   * @exception SecurityException If write access is not allowed to this file
1028
   */
1029
  public boolean mkdirs()
1030
  {
1031
    String parent = getParent();
1032
    if (parent == null)
1033
      {
1034
        return mkdir();
1035
      }
1036
 
1037
    File f = new File(parent);
1038
    if (!f.exists())
1039
      {
1040
        boolean rc = f.mkdirs();
1041
        if (rc == false)
1042
          return false;
1043
      }
1044
 
1045
    return mkdir();
1046
  }
1047
 
1048
  /**
1049
   * This method creates a temporary file in the specified directory.  If
1050
   * the directory name is null, then this method uses the system temporary
1051
   * directory. The files created are guaranteed not to currently exist and
1052
   * the same file name will never be used twice in the same virtual
1053
   * machine instance.
1054
   * The system temporary directory is determined by examinging the
1055
   * <code>java.io.tmpdir</code> system property.
1056
   * <p>
1057
   * The <code>prefix</code> parameter is a sequence of at least three
1058
   * characters that are used as the start of the generated filename.  The
1059
   * <code>suffix</code> parameter is a sequence of characters that is used
1060
   * to terminate the file name.  This parameter may be <code>null</code>
1061
   * and if it is, the suffix defaults to ".tmp".
1062
   * <p>
1063
   * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
1064
   * method is used to verify that this operation is permitted.
1065
   *
1066
   * @param prefix The character prefix to use in generating the path name.
1067
   * @param suffix The character suffix to use in generating the path name.
1068
   * @param directory The directory to create the file in, or
1069
   * <code>null</code> for the default temporary directory
1070
   *
1071
   * @exception IllegalArgumentException If the patterns is not valid
1072
   * @exception SecurityException If there is no permission to perform
1073
   * this operation
1074
   * @exception IOException If an error occurs
1075
   *
1076
   * @since 1.2
1077
   */
1078
  public static synchronized File createTempFile(String prefix, String suffix,
1079
                                    File directory)
1080
    throws IOException
1081
  {
1082
    // Grab the system temp directory if necessary
1083
    if (directory == null)
1084
      {
1085
        String dirname = System.getProperty("java.io.tmpdir");
1086
        if (dirname == null)
1087
          throw new IOException("Cannot determine system temporary directory");
1088
 
1089
        directory = new File(dirname);
1090
        if (! VMFile.exists(directory.path))
1091
          throw new IOException("System temporary directory "
1092
                                + directory.getName() + " does not exist.");
1093
        if (! VMFile.isDirectory(directory.path))
1094
          throw new IOException("System temporary directory "
1095
                                + directory.getName()
1096
                                + " is not really a directory.");
1097
      }
1098
 
1099
    // Check if prefix is at least 3 characters long
1100
    if (prefix.length() < 3)
1101
      throw new IllegalArgumentException("Prefix too short: " + prefix);
1102
 
1103
    // Set default value of suffix
1104
    if (suffix == null)
1105
      suffix = ".tmp";
1106
 
1107
    // Now identify a file name and make sure it doesn't exist.
1108
    File file;
1109
    if (!VMFile.IS_DOS_8_3)
1110
      {
1111
        do
1112
          {
1113
            long now = System.currentTimeMillis();
1114
            if (now > last_tmp)
1115
              {
1116
                // The last temporary file was created more than 1 ms ago.
1117
                last_tmp = now;
1118
                n_created = 0;
1119
              }
1120
            else
1121
              n_created++;
1122
 
1123
            String name = Long.toHexString(now);
1124
            if (n_created > 0)
1125
              name += '_'+Integer.toHexString(n_created);
1126
            String filename = prefix + name + suffix;
1127
            file = new File(directory, filename);
1128
          }
1129
        while (VMFile.exists(file.path));
1130
      }
1131
    else
1132
      {
1133
        // make sure prefix is not longer than 7 characters
1134
        if (prefix.length() >= 8)
1135
          throw new IllegalArgumentException("Prefix too long: " + prefix + "(valid length 3..7)");
1136
 
1137
        long mask = 0x000000ffffFFFFL >> (prefix.length() * 4);
1138
        do
1139
          {
1140
            int n = (int) (System.currentTimeMillis() & mask);
1141
            String filename = prefix + java.lang.Integer.toHexString(n) + suffix;
1142
            file = new File(directory, filename);
1143
          }
1144
        while (VMFile.exists(file.path));
1145
      }
1146
 
1147
    // Verify that we are allowed to create this file
1148
    SecurityManager sm = System.getSecurityManager();
1149
    if (sm != null)
1150
      sm.checkWrite(file.getAbsolutePath());
1151
 
1152
    // Now create the file and return our file object
1153
    // XXX - FIXME race condition.
1154
    VMFile.create(file.getAbsolutePath());
1155
    return file;
1156
  }
1157
 
1158
  /**
1159
   * This method sets the file represented by this object to be read only.
1160
   * A read only file or directory cannot be modified.  Please note that
1161
   * GNU systems allow read only files to be deleted if the directory it
1162
   * is contained in is writable.
1163
   *
1164
   * @return <code>true</code> if the operation succeeded, <code>false</code>
1165
   * otherwise.
1166
   *
1167
   * @exception SecurityException If the <code>SecurityManager</code> does
1168
   * not allow this operation.
1169
   *
1170
   * @since 1.2
1171
   */
1172
  public boolean setReadOnly()
1173
  {
1174
    // Do a security check before trying to do anything else.
1175
    checkWrite();
1176
 
1177
    // Test for existence.
1178
    if (! VMFile.exists(path))
1179
      return false;
1180
 
1181
    return VMFile.setReadOnly(path);
1182
  }
1183
 
1184
  /**
1185
   * This method returns an array of filesystem roots.  Some operating systems
1186
   * have volume oriented filesystem.  This method provides a mechanism for
1187
   * determining which volumes exist.  GNU systems use a single hierarchical
1188
   * filesystem, so will have only one "/" filesystem root.
1189
   *
1190
   * @return An array of <code>File</code> objects for each filesystem root
1191
   * available.
1192
   *
1193
   * @since 1.2
1194
   */
1195
  public static File[] listRoots()
1196
  {
1197
    return VMFile.listRoots();
1198
  }
1199
 
1200
  /**
1201
   * This method creates a temporary file in the system temporary directory.
1202
   * The files created are guaranteed not to currently exist and the same file
1203
   * name will never be used twice in the same virtual machine instance.  The
1204
   * system temporary directory is determined by examinging the
1205
   * <code>java.io.tmpdir</code> system property.
1206
   * <p>
1207
   * The <code>prefix</code> parameter is a sequence of at least three
1208
   * characters that are used as the start of the generated filename.  The
1209
   * <code>suffix</code> parameter is a sequence of characters that is used
1210
   * to terminate the file name.  This parameter may be <code>null</code>
1211
   * and if it is, the suffix defaults to ".tmp".
1212
   * <p>
1213
   * If a <code>SecurityManager</code> exists, then its <code>checkWrite</code>
1214
   * method is used to verify that this operation is permitted.
1215
   * <p>
1216
   * This method is identical to calling
1217
   * <code>createTempFile(prefix, suffix, null)</code>.
1218
   *
1219
   * @param prefix The character prefix to use in generating the path name.
1220
   * @param suffix The character suffix to use in generating the path name.
1221
   *
1222
   * @exception IllegalArgumentException If the prefix or suffix are not valid.
1223
   * @exception SecurityException If there is no permission to perform
1224
   * this operation
1225
   * @exception IOException If an error occurs
1226
   */
1227
  public static File createTempFile(String prefix, String suffix)
1228
    throws IOException
1229
  {
1230
    return createTempFile(prefix, suffix, null);
1231
  }
1232
 
1233
  /**
1234
   * This method compares the specified <code>File</code> to this one
1235
   * to test for equality.  It does this by comparing the canonical path names
1236
   * of the files.
1237
   * <p>
1238
   * The canonical paths of the files are determined by calling the
1239
   * <code>getCanonicalPath</code> method on each object.
1240
   * <p>
1241
   * This method returns a 0 if the specified <code>Object</code> is equal
1242
   * to this one, a negative value if it is less than this one
1243
   * a positive value if it is greater than this one.
1244
   *
1245
   * @return An integer as described above
1246
   *
1247
   * @since 1.2
1248
   */
1249
  public int compareTo(File other)
1250
  {
1251
    if (VMFile.IS_CASE_SENSITIVE)
1252
      return path.compareTo (other.path);
1253
    else
1254
      return path.compareToIgnoreCase (other.path);
1255
  }
1256
 
1257
  /**
1258
   * This method compares the specified <code>Object</code> to this one
1259
   * to test for equality.  It does this by comparing the canonical path names
1260
   * of the files.  This method is identical to <code>compareTo(File)</code>
1261
   * except that if the <code>Object</code> passed to it is not a
1262
   * <code>File</code>, it throws a <code>ClassCastException</code>
1263
   * <p>
1264
   * The canonical paths of the files are determined by calling the
1265
   * <code>getCanonicalPath</code> method on each object.
1266
   * <p>
1267
   * This method returns a 0 if the specified <code>Object</code> is equal
1268
   * to this one, a negative value if it is less than this one
1269
   * a positive value if it is greater than this one.
1270
   *
1271
   * @return An integer as described above
1272
   *
1273
   * @exception ClassCastException If the passed <code>Object</code> is
1274
   * not a <code>File</code>
1275
   *
1276
   * @since 1.2
1277
   */
1278
  public int compareTo(Object obj)
1279
  {
1280
    return compareTo((File) obj);
1281
  }
1282
 
1283
  /**
1284
   * This method renames the file represented by this object to the path
1285
   * of the file represented by the argument <code>File</code>.
1286
   *
1287
   * @param dest The <code>File</code> object representing the target name
1288
   *
1289
   * @return <code>true</code> if the rename succeeds, <code>false</code>
1290
   * otherwise.
1291
   *
1292
   * @exception SecurityException If write access is not allowed to the
1293
   * file by the <code>SecurityMananger</code>.
1294
   */
1295
  public synchronized boolean renameTo(File dest)
1296
  {
1297
    checkWrite();
1298
    dest.checkWrite();
1299
    // Call our native rename method
1300
    return VMFile.renameTo(path, dest.path);
1301
  }
1302
 
1303
  /**
1304
   * This method sets the modification time on the file to the specified
1305
   * value.  This is specified as the number of seconds since midnight
1306
   * on January 1, 1970 GMT.
1307
   *
1308
   * @param time The desired modification time.
1309
   *
1310
   * @return <code>true</code> if the operation succeeded, <code>false</code>
1311
   * otherwise.
1312
   *
1313
   * @exception IllegalArgumentException If the specified time is negative.
1314
   * @exception SecurityException If the <code>SecurityManager</code> will
1315
   * not allow this operation.
1316
   *
1317
   * @since 1.2
1318
   */
1319
  public boolean setLastModified(long time)
1320
  {
1321
    if (time < 0)
1322
      throw new IllegalArgumentException("Negative modification time: " + time);
1323
 
1324
    checkWrite();
1325
    return VMFile.setLastModified(path, time);
1326
  }
1327
 
1328
  private void checkWrite()
1329
  {
1330
    // Check the SecurityManager
1331
    SecurityManager s = System.getSecurityManager();
1332
 
1333
    if (s != null)
1334
      s.checkWrite(path);
1335
  }
1336
 
1337
  private void checkRead()
1338
  {
1339
    // Check the SecurityManager
1340
    SecurityManager s = System.getSecurityManager();
1341
 
1342
    if (s != null)
1343
      s.checkRead(path);
1344
  }
1345
 
1346
  /**
1347
   * Calling this method requests that the file represented by this object
1348
   * be deleted when the virtual machine exits.  Note that this request cannot
1349
   * be cancelled.  Also, it will only be carried out if the virtual machine
1350
   * exits normally.
1351
   *
1352
   * @exception SecurityException If deleting of the file is not allowed
1353
   *
1354
   * @since 1.2
1355
   */
1356
  public void deleteOnExit()
1357
  {
1358
    // Check the SecurityManager
1359
    SecurityManager sm = System.getSecurityManager();
1360
    if (sm != null)
1361
      sm.checkDelete(path);
1362
 
1363
    DeleteFileHelper.add(this);
1364
  }
1365
 
1366
  private void writeObject(ObjectOutputStream oos) throws IOException
1367
  {
1368
    oos.defaultWriteObject();
1369
    oos.writeChar(separatorChar);
1370
  }
1371
 
1372
  private void readObject(ObjectInputStream ois)
1373
    throws ClassNotFoundException, IOException
1374
  {
1375
    ois.defaultReadObject();
1376
 
1377
    // If the file was from an OS with a different dir separator,
1378
    // fixup the path to use the separator on this OS.
1379
    char oldSeparatorChar = ois.readChar();
1380
 
1381
    if (oldSeparatorChar != separatorChar)
1382
      path = path.replace(oldSeparatorChar, separatorChar);
1383
  }
1384
 
1385
} // class File
1386
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.