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

Subversion Repositories scarts

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

powered by: WebSVN 2.1.0

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