afrag  
          記錄學(xué)習(xí)和成長(zhǎng)的歷程
          日歷
          <2010年3月>
          28123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910
          統(tǒng)計(jì)
          • 隨筆 - 9
          • 文章 - 5
          • 評(píng)論 - 2
          • 引用 - 0

          導(dǎo)航

          常用鏈接

          留言簿

          隨筆分類(lèi)

          隨筆檔案

          文章檔案

          搜索

          •  

          積分與排名

          • 積分 - 10284
          • 排名 - 2368

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

           

          2010年3月29日

          轉(zhuǎn)自 開(kāi)發(fā)者的天空

          本文中我們來(lái)討論在NIO2中怎樣創(chuàng)建文件、讀取文件和寫(xiě)文件。NIO2提供了多種創(chuàng)建 文件的方法,使得我們?cè)趧?chuàng)建文件的時(shí)候就可以指定文件的某些初始屬性。例如在支持POSIX的文件系統(tǒng)上指定文件的所有者,訪問(wèn)權(quán)限等。關(guān)于文件的屬性, 請(qǐng)看上一篇文章Java SE 7新特性之文件操作(5) - 管理元數(shù)據(jù)
          創(chuàng)建文件
          可以調(diào)用createFile(FileAttribute<?>)方法創(chuàng)建一個(gè)空文件。該方法的參數(shù)就是文件的初始屬性。下面的例子是怎樣 在創(chuàng)建文件的時(shí)候賦予該文件某些權(quán)限的屬性:
          Path sourceFile = ;
          Path newFile 
          = ;
          PosixFileAttributes attrs 
          = Attributes.readPosixFileAttributes(sourceFile);
          FileAttribute
          <Set<PosixFilePermission>> attr =
                    PosixFilePermissions.asFileAttribute(attrs.permissions());
          try {
              file.createFile(attr);
          catch (IOException x) {
              
          //unable to create the file
          }
          如 果在調(diào)用該方法的時(shí)候沒(méi)有傳入任何參數(shù),那么創(chuàng)建的文件將具有缺省的文件屬性。下面的代碼創(chuàng)建了一個(gè)具有缺省文件屬性的文件:
          Path file = ;
          try {
              file.createFile();   
          //Create the empty file with default permissions, etc.
          catch (FileAlreadyExists x) {
              System.err.format(
          "file named %s already exists%n", file);
          catch (IOException x) {
              
          //Some other sort of failure, such as permissions.
              System.err.format("createFile error: %s%n", x);
          }
          如 果要?jiǎng)?chuàng)建的文件已經(jīng)存在,該方法會(huì)拋出異常。
          注意在調(diào)用createFile方法時(shí),檢查文件是否存在和創(chuàng)建具有特定的屬性的文件是在同一個(gè)原子操作中。
          還可以使用newOutputSteam方法來(lái)創(chuàng)建文件,在本文的后面我們會(huì)講到怎樣使用newOutputStream方法來(lái)創(chuàng)建文件。
          通過(guò)Stream I/O讀文件
          我們可以通過(guò)newInputStream(OpenOption...)方法打開(kāi)和讀取文件。這個(gè)方法返回一個(gè)unbuffered輸入流(input stream),我們可以用它來(lái)從文件中讀取字節(jié)內(nèi)容。
          Path file = ;
          InputStream in 
          = null;
          try {
              in 
          = file.newInputStream();
              BufferedReader reader 
          = new BufferedReader(new InputStreamReader(in));
              String line 
          = null;
              
          while ((line = reader.readLine()) != null) {
                  System.out.println(line);
              }
          catch (IOException x) {
              System.err.println(x);
          finally {
              
          if (in != null) in.close();
          }
          注 意該方法接受可變個(gè)數(shù)的參數(shù),參數(shù)類(lèi)型為OpenOption,指定了文件怎樣打開(kāi)。如果不傳入?yún)?shù),則使用默認(rèn)的READ方式打開(kāi)。READ方式是所有 的實(shí)現(xiàn)都支持的方式。有一些實(shí)現(xiàn)也支持其他的打開(kāi)方式。
          如果傳入的OpenOption或其組合不正確,會(huì)拋出異常。如果程序沒(méi)有讀權(quán)限或I/O錯(cuò)誤,也會(huì)拋出異常。
          Creating and Writing a File by Using Stream I/O
          使用Stream I/O來(lái)創(chuàng)建和寫(xiě)文件
          我們可以使用newOutputStream方法來(lái)創(chuàng)建文件、擴(kuò)展文件或覆蓋已有文件。這個(gè)方法為了寫(xiě)文件而打開(kāi)或創(chuàng)建文件,該方法返回一個(gè) unbuffered的輸出流(output stream)。newOutputStream方法有兩種形式:

          • newOutputStream(OpenOption...)
          • newOutputStream(Set<? extends OpenOption>, FileAttribute<?>...)

          這兩種形式都接受一組OpenOption作為參數(shù),第二種形式還允許指定初始的文件屬性。這個(gè)方法支持的StandardOpenOption有:

          • WRITE –為了寫(xiě)訪問(wèn)而打開(kāi)該文件.
          • APPEND – 將新數(shù)據(jù)擴(kuò)展在文件的末尾。該選項(xiàng)和WRITE或CREATE選項(xiàng)一起使用。
          • TRUNCATE_EXISTING – 將文件截?cái)酁?字節(jié)長(zhǎng). 該選項(xiàng)和WRITE選項(xiàng)一起使用來(lái)覆蓋原有文件。
          • CREATE_NEW – 創(chuàng)建一個(gè)新的文件。如果原來(lái)的文件存在這拋出異常。
          • CREATE – 如果原文件存在這打開(kāi)它,否則創(chuàng)建新的文件。
          • DELETE_ON_CLOSE – 當(dāng)Stream關(guān)閉時(shí)刪除該文件。這個(gè)選項(xiàng)對(duì)臨時(shí)文件比較有用。
          • SPARSE – 表明新創(chuàng)建的文件是Sparse文件. 關(guān)于Sparse文件的具體信息請(qǐng)看http://space.itpub.net/8242091/viewspace-619756
          • SYNC – 保持該文件(包括內(nèi)容和元數(shù)據(jù))與底層存儲(chǔ)設(shè)備同步。
          • DSYNC – 保持文件內(nèi)容與底層存儲(chǔ)設(shè)備同步。

          如果沒(méi)有指定OpenOption,該方法的行為是:如果文件不存在,則創(chuàng)建新文件;如果文件存在,那么截?cái)嗨R簿褪钦f(shuō)缺省的選擇是CREATE和 TRUNCATE_EXISTING選項(xiàng)的組合。
          下面的代碼打開(kāi)一個(gè)日志文件,如果文件不存在,則創(chuàng)建一個(gè)新文件。如果文件 存在,這將新的內(nèi)容擴(kuò)展到文件尾部。
          import static java.nio.file.StandardOpenOption.*;

          Path logfile 
          = ;

          //Convert the string to a byte array.
          String s = ;
          byte data[] = s.getBytes();

          OutputStream out 
          = null;
          try {
              out 
          = new BufferedOutputStream(logfile.newOutputStream(CREATE, APPEND));
              
              out.write(data, 
          0, data.length);
          catch (IOException x) {
              System.err.println(x);
          finally {
              
          if (out != null) {
                  out.flush();
                  out.close();
              }
          }

          使用Channel I/O來(lái)讀寫(xiě)文件
          Stream I/O每次讀取一個(gè)字符,Channel I/O每次讀取一個(gè)緩沖塊的數(shù)據(jù)。ByteChannel接口提供了基本的讀寫(xiě)功能。SeekableByteChannel擴(kuò)展了 ByteChannel并提供了維護(hù)一個(gè)channel中的位置并改變?cè)撐恢玫哪芰ΑeekableByteChannel還支持截?cái)辔募筒樵?xún)文件大 小的功能。
          移動(dòng)到文件中不同的位置,從該位置開(kāi)始讀或?qū)懙哪芰κ刮覀兛梢?span onclick="tagshow(event)" class="t_tag">隨機(jī)訪問(wèn)文件。有兩種形式的 newByteChannel方法可以用來(lái)讀或?qū)懳募@兩種形式和newOutputStream方法一樣。

          • newByteChannel(OpenOption...)
          • newByteChannel(Set<? extends OpenOption>, FileAttribute<?>...)

          這兩個(gè)方法都允許指定OpenOption,newOutputStream所支持的選擇這里也支持,而且這里還支持另外一個(gè)選項(xiàng)READ,因?yàn)? SeekableByteChannel既支持讀也支持寫(xiě)。
          如果選項(xiàng)是READ,那么該channel就是為了讀訪問(wèn)打開(kāi)。如果選項(xiàng)是WRITE或APPEND,則該channel就是為了寫(xiě)訪問(wèn)打開(kāi)。如果沒(méi)有指 定,該channel默認(rèn)是為了讀打開(kāi)。
          下面的代碼從文件中讀取內(nèi)容并輸出到控制臺(tái)上:
          SeekableByteChannel sbc = null;
          try {
              sbc 
          = file.newByteChannel();  //Defaults to READ
              ByteBuffer buf = ByteBuffer.allocate(10);

              
          //Read the bytes with the proper encoding for this platform.
              
          //If you skip this step, you might see something that looks like Chinese
              
          //characters when you expect Latin-style characters.
              String encoding = System.getProperty("file.encoding");
              
          while (sbc.read(buf) > 0) {
                  buf.rewind();
                  System.out.print(Charset.forName(encoding).decode(buf));
                  buf.flip();
              }
          catch (IOException x) {
              System.out.println(
          "caught exception: " + x);
          finally {
              
          if (sbc != null) sbc.close();
          }
          下 面的代碼是為了UNIX或其他支持POSIX的文件系統(tǒng)編寫(xiě)的。這段代碼創(chuàng)建一個(gè)新的日志文件或者擴(kuò)展原有的日志文件,該日志文件創(chuàng)建時(shí)指定了訪問(wèn)權(quán)限 (所有者有讀寫(xiě)權(quán)限,同組用戶只有讀權(quán)限,其他用戶沒(méi)有讀權(quán)限)。
          import static java.nio.file.StandardCopyOption.*;

          //Create the set of options for appending to the file.
          Set<OpenOptions> options = new HashSet<OpenOption>();
          options.add(APPEND);
          options.add(CREATE);

          //Create the custom permissions attribute.
          Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-r------");
          FileAttribute
          <Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);

          //Convert the string to a ByetBuffer.
          String s = ;
          byte data[] = s.getBytes();
          ByteBuffer bb 
          = ByteBuffer.wrap(data);

          SeekableByteChannel sbc 
          = null;
          try {
              sbc 
          = file.newByteChannel(options, attr);
              sbc.write(bb);
          catch (IOException x) {
              System.out.println(
          "exception thrown: " + x);
          finally {
              
          if (sbc != null) sbc.close();
          }
          posted @ 2010-04-05 17:30 afrag 閱讀(503) | 評(píng)論 (0)編輯 收藏
           
          轉(zhuǎn)自 開(kāi)發(fā)者的天空

          管理元數(shù)據(jù)(文件屬性和文件存儲(chǔ)屬性)
          在文件系統(tǒng)中,文件或者目錄的元數(shù)據(jù)是和文件或者目錄本身存儲(chǔ)在一起的,而且元數(shù)據(jù)保存了很多的信息,例如:對(duì)象是文件還是目錄,抑或是符號(hào)鏈接。文件的大小、創(chuàng)建 時(shí)間、最后修改時(shí)間、文件的所有者、組、訪問(wèn)權(quán)限等。
          java.nio.file.attribute包提供了訪問(wèn)和管理文件系統(tǒng)元數(shù)據(jù)(通常叫做文件屬性)的功能。不同的文件系統(tǒng)提供的文件屬性是不一樣 的,所以我們按照這個(gè)將文件的屬性劃分成了不同的視圖(View)。每個(gè)View對(duì)應(yīng)一個(gè)文件系統(tǒng)的實(shí)現(xiàn),如POSIX(Unix使用的文件系統(tǒng))或 DOS;或者是所有文件系統(tǒng)共有的屬性,如文件的所有權(quán)。當(dāng)我們讀取文件的屬性的時(shí)候,是一次讀取整個(gè)視圖的屬性的。Java所支持的視圖有:
          BasicFileAttributeView – 所有的文件系統(tǒng)實(shí)現(xiàn)都必須提供的屬性的視圖。
          DosFileAttributeView – 擴(kuò)展了BasicFileAttributeView,添加了DOS文件系統(tǒng)能夠支持的幾種屬性。
          PosixFileAttributeView – 擴(kuò)展了BasicFileAttributeView,添加了POSIX文件系統(tǒng)能夠支持的幾種屬性。
          FileOwnerAttributeView – 任何文件系統(tǒng)實(shí)現(xiàn)都會(huì)支持文件所有者的屬性。這個(gè)View就包含這個(gè)屬性。
          AclFileAttributeView – 支持讀取和更新文件的訪問(wèn)控制列表。支持NFSv4訪問(wèn)控制列表模型。所有定義了到NFSv4的映射的訪問(wèn)控制列表模型也同樣支持,如Windows的訪 問(wèn)控制列表模型。
          UserDefinedFileAttributeView – 支持用戶自定義的元數(shù)據(jù)。這個(gè)View可以被映射到文件系統(tǒng)提供的擴(kuò)展機(jī)制。例如在Solaris操作系統(tǒng)上,可以將這個(gè)View存儲(chǔ)MIMEtype。
          不同的文件系統(tǒng)可能支持不同的一個(gè)或幾個(gè)view,也有可能含有上面所有的View都沒(méi)有包含的文件屬性。
          Attributes類(lèi)
          大多數(shù)情況下,我們不需要直接使用FileAttributeView接口,Attributes類(lèi)提供了轉(zhuǎn)換的方法來(lái)讀取和設(shè)置文件屬性。
          下面是Attributes類(lèi)提供的一些方法:
          讀取或設(shè)置基本的文件屬性:
          readBasicFileAttributes(FileRef, LinkOption...)
          setLastAccessTime(FileRef, FileTime)
          setLastModifiedTime(FileRef, FileTime)

          讀取或設(shè)置POSIX文件屬性
          readPosixFileAttributes(FileRef, LinkOption...)
          setPosixFilePermissions(FileRef, Set<PosixFilePermission>)

          讀取或設(shè)置文件的所有者
          getOwner(FileRef)
          setOwner(FileRef, UserPrincipal)

          一次讀取所有的文件屬性
          readAttributes(FileRef, String, LinkOption...)

          讀取或設(shè)定特定的文件屬性
          getAttribute(FileRef, String, LinkOption...)
          setAttribute(FileRef, String, Object)

          讀取DOS文件屬性
          readDosFileAttributes(FileRef, LinkOption...)

          讀取或設(shè)置文件的訪問(wèn)控制列表。
          getAcl(FileRef)
          setAcl(FileRef, List<AclEntry>)

          讀取文件存儲(chǔ)空間的屬性,如總空間、有效空間、未分配空間等。
          readFileStoreSpaceAttributes(FileStore)

          每個(gè)read方法都返回一個(gè)對(duì)象,該對(duì)象會(huì)提供訪問(wèn)方法,我們通過(guò)這些訪問(wèn)方法能夠很方便的獲得特定的文件屬性的值。
          要想讀取基本的文件信息,那么可以調(diào)用readBasicFileAttributes(FileRef, LinkOption...)方法。這個(gè)方法支持的LinkOption就只有NOFOLLOW_LINKS。這個(gè)方法會(huì)一次性的讀取所有的基本的文件屬 性并返回一個(gè)BasicFileAttributes對(duì)象,我們可以訪問(wèn)該對(duì)象獲取具體的文件屬性。如果程序?qū)ξ募](méi)有訪問(wèn)權(quán)限,該方法會(huì)拋出 SecurityException異常。要注意的是,并不是所有文件系統(tǒng)的實(shí)現(xiàn)都支持創(chuàng)建時(shí)間、最后修改時(shí)間和最后訪問(wèn)時(shí)間這三個(gè)屬性。如果某個(gè)屬性不 被支持,則調(diào)用該屬性的get方法時(shí)會(huì)返回null。下面就是一個(gè)讀取文件的基本屬性的例子:
          Path file = ;
          BasicFileAttributes attr 
          = Attributes.readBasicFileAttributes(file);

          if (attr.creationTime() != null) {
              System.out.println(
          "creationTime: " + attr.creationTime());
          }
          if (attr.lastAccessTime() != null) {
              System.out.println(
          "lastAccessTime: " + attr.lastAccessTime());
          }
          if (attr.lastModifiedTime() != null) {
              System.out.println(
          "lastModifiedTime: " + attr.lastModifiedTime());
          }

          System.out.println(
          "isDirectory: " + attr.isDirectory());
          System.out.println(
          "isOther: " + attr.isOther());
          System.out.println(
          "isRegularFile: " + attr.isRegularFile());
          System.out.println(
          "isSymbolicLink: " + attr.isSymbolicLink());
          System.out.println(
          "size: " + attr.size());
          下面的例子中,我們檢查了對(duì)一個(gè)文件的訪問(wèn)權(quán)限,判斷 該文件是常規(guī)的文件還是目錄:
             import static java.nio.file.AccessMode.*;
            

             Path file 
          = ;
             
          boolean error=false;
            

             
          try {
                 file.checkAccess(READ, EXECUTE);
                 
          if (!Attributes.readBasicFileAttributes(file).isRegularFile()) {
                     error 
          = true;
                 }
             } 
          catch (IOException x) {
                 
          //Logic for error condition
                 error = true;
             }
             
          if (error) {
                 
          //Logic for failure
                 return;
             }
             
          //Logic for executable file

          設(shè)置 時(shí)間戳

          前面的文件基本屬性的代碼中演示了怎樣獲取文件的時(shí)間戳,Attributes類(lèi)還提供了兩個(gè)方法來(lái)設(shè)置時(shí)間戳:setLastAccessTime和 setLastModifiedTime,下面是這兩個(gè)方法的示例:
          Path file = ;
          BasicFileAttributes attr 
          = Attributes.readBasicFileAttributes(file);
          long currentTime = System.currentTimeMillis();
          if (attr.lastModifiedTime() != null) {
              FileTime ft 
          = FileTime.fromMillis(currentTime);
              Attributes.setLastModifiedTime(file, ft);
          else {
              System.err.println(
          "lastModifiedTime time stamp not supported");
          }

          DOS的文件屬性
          要獲取一個(gè)文件的DOS的文件屬性,需要調(diào)用readDosFileAttributes方法。這個(gè)方法會(huì)返回一個(gè)DosFileAttributes對(duì) 象,該對(duì)象提供了獲取DOS文件屬性的方法,例如:
          Path file = ;
          try {
              DosFileAttributes attr 
          = Attributes.readDosFileAttributes(file);
              System.out.println(
          "isReadOnly is " + attr.isReadOnly());
              System.out.println(
          "isHidden is " + attr.isHidden());
              System.out.println(
          "isArchive is " + attr.isArchive());
              System.out.println(
          "isSystem is " + attr.isSystem());
          catch (IOException x) {
              System.err.println(
          "DOS file attributes not supported:" + x);
          }


          我 們可以使用setAttribute方法來(lái)設(shè)置DOS文件屬性,如:
          Path file = ;
          Attributes.setAttribute(file, 
          "dos:hidden"true);

          要注意的是,不是只有DOS操作系統(tǒng)才支持DOS文 件屬性,有些操作系統(tǒng)如Samba也支持DOS文件屬性。
          POSIX的文件屬性
          POSIX是Portable Operation System Interface for UNIX的縮寫(xiě),而且IEEE和ISO定義很多標(biāo)準(zhǔn)來(lái)保證不同的UNIX之間的戶操作性,因此對(duì)于開(kāi)發(fā)人員來(lái)說(shuō),針對(duì)POSIX編寫(xiě)的程序能夠很容易的運(yùn) 行在不同的兼容POSIX的文件系統(tǒng)上。
          要讀取POSIX文件屬性,需要調(diào)用readPosixFileAttributes方法。除了文件所有者和所屬組,POSIX還支持9種文件權(quán)限許可組 合:讀、寫(xiě)、執(zhí)行三種權(quán)限和文件所有者、同組的用戶和其他用戶三種角色的組合(3 × 3 = 9)。下面就是讀取POSIX文件屬性的簡(jiǎn)單的例子:
          Path file = ;
          PosixFileAttributes attr 
          = Attributes.readPosixFileAttributes(file);
          System.out.format(
          "%s %s %s%n", attr.owner().getName, attr.group().getName(),
                            PosixFilePermissions.toString(attr.permissions()));

          下面的代碼讀取了一個(gè)文件的屬性,然后創(chuàng)建了一個(gè)新的 文件,將原有的文件的權(quán)限屬性賦予新創(chuàng)建的文件:

          Path sourceFile = ;
          Path newFile 
          = ;
          PosixFileAttributes attrs 
          = Attributes.readPosixFileAttributes(sourceFile);
          FileAttribute
          <Set<PosixFilePermission>> attr =
                    PosixFilePermissions.asFileAttribute(attrs.permissions());
          try {
              file.createFile(attr);
          catch (IOException x) {
              
          //unable to create the file
          }
          上 面的代碼中我們使用了PosixFilePermission類(lèi),該類(lèi)是一個(gè)幫助類(lèi),提供了一些方法來(lái)讀取和生成文件權(quán)限,這里就不詳細(xì)解釋了。
          如果想指定創(chuàng)建的文件的權(quán)限,可以使用下面的代碼:
          Path file = ;
          Set
          <PosixFilePermission> perms = PosixFilePermissions.fromString("rw-------");
          FileAttribute
          <Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(perms);
          try {
              Attributes.setPosixFilePermissions(file, perms);
          catch (IOException x) {
              System.err.println(x);
          }
          文 件有所有者的屬性和所屬組的屬性,在設(shè)置這些屬性的時(shí)候,我們需要傳入一個(gè)UserPrincipal對(duì)象作為參數(shù),我們可以使用 UserPrincipalLookupService來(lái)根據(jù)用戶名或組名來(lái)創(chuàng)建該對(duì)象。UserPrincipalLookupService實(shí)例可以 通過(guò)FileSystem.getUserPrincipalLookupService方法獲得。下面就是設(shè)置所有者屬性的例子:
          Path file = ;
          try {
              UserPrincipal owner 
          = file.GetFileSystem().getUserPrincipalLookupService()
                                    .lookupPrincipalByName(
          "sally");
              Attributes.setOwner(file, owner);
          catch (IOException x) {
              System.err.println(x);
          }
          Attributes 類(lèi)沒(méi)有提供設(shè)置所屬組的方法,如果要設(shè)置所屬組,需要調(diào)用POSIX文件屬性視圖來(lái)進(jìn)行,下面是示例代碼:
          Path file = ;
          try {
              GroupPrincipal group 
          = file.getFileSystem().getUserPrincipalLookupService()
                                    .lookupPrincipalByGroupName(
          "green");
              file.getFileAttributeView(PosixFileAttributeView.
          class).setGroup(group);
          catch (IOException x) {
              System.err.println(x);
          }

          用戶定義的文件屬性
          如果文件系統(tǒng)支持的屬性對(duì)你來(lái)說(shuō)還不夠用,你可以通過(guò)UserDefinedAttributeView來(lái)創(chuàng)建和跟蹤自己的文件屬性。
          下面的例子中,我們將MIME類(lèi)型作為一個(gè)用戶自定義的屬性:
          Path file = ;
          UserDefinedFileAttributeView view 
          = file
              .getFileAttributeView(UserDefinedFileAttributeView.
          class);
          view.write(
          "user.mimetype", Charset.defaultCharset().encode("text/html");
          要讀取MIME類(lèi)型屬性,要使用以下的代碼:
          Path file = ;
          UserDefinedFileAttributeView view 
          = file
              .getFileAttributeView(UserDefinedFileAttributeView.
          class);
          String name 
          = "user.mimetype";
          ByteBuffer buf 
          = ByteBuffer.allocate(view.size(name));
          view.read(name, buf);
          buf.flip();
          String value 
          = Charset.defaultCharset().decode(buf).toString();
          如果文件系統(tǒng)不支持?jǐn)U展屬性,那么會(huì)拋出一個(gè) UnsupportedOperationException異常,你可以咨詢(xún)系統(tǒng)管理員來(lái)確認(rèn)系統(tǒng)是否支持文件的擴(kuò)展屬性并進(jìn)行相應(yīng)的配置。

          文件存儲(chǔ)屬性
          文件存儲(chǔ)屬性其實(shí)我們應(yīng)該非常熟悉的屬性,我們查看硬盤(pán)屬性的時(shí)候,經(jīng)常看到硬盤(pán)總的存儲(chǔ)空間,使用了的存儲(chǔ)空間,空閑的存儲(chǔ)空間等就是文件存儲(chǔ)屬性。下 面是獲取文件存儲(chǔ)屬性的代碼:
          Path file = ;
          FileStore store 
          = file.getFileStore();
          FileStoreSpaceAttributes attr 
          = Attributes.readFileStoreSpaceAttributes(store);

          System.out.println(
          "total: " + attr.totalSpace() );
          System.out.println(
          "used:  " + (attr.totalSpace() - attr.unallocatedSpace()) );
          System.out.println(
          "avail: " + attr.usableSpace() );

          posted @ 2010-04-01 10:49 afrag 閱讀(388) | 評(píng)論 (0)編輯 收藏
           

          轉(zhuǎn)自開(kāi)發(fā)者的天空

          刪除操作

          通過(guò)Path類(lèi),我們可以刪除文件、目錄或符號(hào)鏈接。要注意的是當(dāng)我們刪除符號(hào)鏈接時(shí),其指向的目的目錄或文件不會(huì)被刪除。當(dāng)要?jiǎng)h除一個(gè)目錄時(shí),該目錄必須為空,否則會(huì)失敗。

          Path類(lèi)提供了兩個(gè)刪除方法。第一個(gè)是delete方法。Delete方法會(huì)直接刪除文件或目錄,如果刪除失敗則會(huì)拋出異常。例如如果要?jiǎng)h除的文件不存在,則會(huì)拋出NoSuchFileException。程序員可以catch這些異常并進(jìn)行相應(yīng)的處理。

          try {
              path.delete();
          catch (NoSuchFileException x) {
              System.err.format(
          "%s: no such file or directory%n", path);
          catch (DirectoryNotEmptyException x) {
              System.err.format(
          "%s not empty%n", path);
          catch (IOException x) {
              //File permission problems are caught here.
              System.err.println(x);
          }


          另外一個(gè)方法是deleteIfExists。這個(gè)方法同樣會(huì)刪除文件或目錄,和delete方法唯一不同的是如果文件不存在,這個(gè)方法不會(huì)拋出異常。


          拷貝操作

          Path類(lèi)提供了拷貝文件或目錄的方法,就是copyTo方法。(以前要copy文件只能夠自己寫(xiě)程序完成哦!)。在進(jìn)行拷貝的時(shí)候,我們可以指定如果目標(biāo)文件或目錄已經(jīng)存在時(shí)怎么處理;如果設(shè)置了REPLACE_EXISTING,則會(huì)覆蓋已有的文件或目錄;如果沒(méi)有設(shè)置 REPLACE_EXISTING,那么拷貝操作會(huì)失敗。

          要注意的是拷貝目錄時(shí),目錄中的內(nèi)容并沒(méi)有被拷貝過(guò)去,新生成的目錄會(huì)是一個(gè)空目錄。要想將目錄中的內(nèi)容一起拷貝過(guò)去,只有自己編程了。

          在拷貝符號(hào)鏈接時(shí),默認(rèn)的行為是拷貝符號(hào)鏈接指向的目的文件或目錄。如果需要拷貝符號(hào)鏈接本身,需要指定NOFOLLOW_LINKS REPLACE_EXISTING選項(xiàng)。

          CopyTo方法接受CopyOption類(lèi)型的varargsCopyOption是一個(gè)接口,目前有兩個(gè)實(shí)現(xiàn)類(lèi):StandardCopyOptionLinkOptionCopyTo方法能夠支持的選項(xiàng)有:

          * REPLACE_EXISTING – 當(dāng)要拷貝的是文件是,如果目標(biāo)文件已經(jīng)存在,則覆蓋目標(biāo)文件。如果要拷貝的是目錄,當(dāng)目標(biāo)目錄已經(jīng)存在時(shí),如果目標(biāo)目錄為空,覆蓋目標(biāo)目錄;如果目標(biāo)目錄不為空,拋出FileAlreadyExistsException。如果要拷貝的是符號(hào)鏈接,那么拷貝符號(hào)鏈接本身。

          * COPY_ATTRIBUTES – 連文件或目錄的屬性一起拷貝。不同的文件系統(tǒng)和平臺(tái)支持不同的文件屬性,但是所有的文件系統(tǒng)和平臺(tái)都支持最后修改時(shí)間這個(gè)屬性。

          * NOFOLLOW_LINKS – 如果要拷貝的是符號(hào)鏈接,直接拷貝符號(hào)鏈接本身。

          下面是使用copyTo的代碼例子:

          import static java.nio.file.StandardCopyOption.*;

          try {
              path.copyTo(newPath, REPLACE_EXISTING,     COPY_ATTRIBUTES);
          catch (IOException x) {
              
          //Logic for error condition
              System.err.println(x);
              
          return;
          }


          移動(dòng)操作

          Path還提供了moveTo方法來(lái)移動(dòng)文件或目錄。如果沒(méi)有設(shè)置REPLACE_EXISTING選項(xiàng),那么當(dāng)目標(biāo)文件或目錄存在時(shí),操作會(huì)失敗。

          空目錄能夠被移動(dòng),但是如果目錄不為空,是否能夠移動(dòng)目錄要取決于是否能夠不移動(dòng)目錄的內(nèi)容。例如在Windows系統(tǒng)下,如果是同一個(gè)硬盤(pán)分區(qū)內(nèi)的移動(dòng),就可以成功,但是如果是不同硬盤(pán)分區(qū)之間的移動(dòng),就會(huì)失敗,會(huì)拋出FileSystemException異常。同時(shí)要注意的是,目的目錄的父目錄一定要存在,否則會(huì)拋出NoSuchFileException。例如將c:"temp"test移動(dòng)到c:"save"test,如果c:"save目錄不存在,則會(huì)拋出異常。

          MoveTo方法也接受可變數(shù)量的參數(shù),其支持的選項(xiàng)有:

          REPLACE_EXISTING – 覆蓋已經(jīng)存在的文件或目錄。如果目標(biāo)文件/目錄是一個(gè)符號(hào)鏈接,那么該鏈接會(huì)被覆蓋,但是起指向的文件或目錄不會(huì)受到影響。 * ATOMIC_MOVE – 移動(dòng)操作是一個(gè)原子操作。如果文件系統(tǒng)不支持移動(dòng)的原子操作,會(huì)拋出異常。原子操作能夠保證當(dāng)你移動(dòng)一個(gè)文件到一個(gè)目錄中時(shí),監(jiān)視該目錄的進(jìn)程得到的是一個(gè)完整的文件。

          下面是使用moveTo方法的例子

          import static java.nio.file.StandardCopyOption.*;

          try {
              path.moveTo(newPath, REPLACE_EXISTING);
          catch (IOException x) {
              
          // Logic for error condition
              System.err.println(x);
              
          return;
          }


          posted @ 2010-03-30 10:32 afrag 閱讀(433) | 評(píng)論 (0)編輯 收藏
           
          轉(zhuǎn)自開(kāi)發(fā)者的天空

          Path類(lèi)提供了很多方法來(lái)對(duì)文件和目錄進(jìn)行讀、寫(xiě)和其他的操作。在看這些方法之前,我們先需要了解一些其他的概念:

          Varargs實(shí)際上是Variable number of arguments的縮寫(xiě),也就是可變數(shù)目的參數(shù)。例如在下面的方法聲明中,CopyOption參數(shù)后面的省略號(hào)表明這個(gè)方法接受可變個(gè)數(shù)的參數(shù)。
                  Path moveTo(Path, CopyOption...)
          當(dāng)一個(gè)方法可以接受可變數(shù)目的參數(shù)時(shí),你可以傳入以逗號(hào)分隔的多個(gè)參數(shù),或者傳入一個(gè)數(shù)組。
          對(duì)于上面的moveTo方法,可以這樣調(diào)用:
          import static java.nio.file.StandardCopyOption.*;

                  Path orig 
          = ;
                  Path 
          new = ;
                  orig.moveTo(
          new, REPLACE_EXISTING, ATOMIC_MOVE);


          Path的很多方法在文件系統(tǒng)上執(zhí)行的操作都是原子操作,例如moveTo方法。原子操作是指不會(huì)被中斷或不會(huì)部分執(zhí)行的操作。操作要么是完全成功,要么是完全失敗。當(dāng)有多個(gè)進(jìn)程操作同文件系統(tǒng)的相同的區(qū)域的時(shí)候這一點(diǎn)就很重要。


          很多的文件I/O方法支持方法鏈的概念。
          調(diào)用第一個(gè)方法會(huì)返回一個(gè)對(duì)象,我們可以直接調(diào)用這個(gè)對(duì)象的方法,這個(gè)方法依然返回一個(gè)對(duì)象,我們又可以直接調(diào)用該對(duì)象的方法,就這樣持續(xù)下去。例如:
                  String value = Charset.defaultCharset().decode(buf).toString();
                  UserPrincipal group = file.getFileSystem().getUserPrincipalLookupService().lookupPrincipalByName("me");
          這個(gè)技術(shù)能夠使我們編寫(xiě)更加緊湊的代碼,避免聲明一些我們不需要的臨時(shí)變量。


          Path類(lèi)實(shí)現(xiàn)了FileRef接口。FileRef接口包含了定位文件和訪問(wèn)文件的方法。


          Path類(lèi)有兩個(gè)方法能夠接受帶模式匹配的參數(shù)。下面是這種參數(shù)的規(guī)則:
          星號(hào)*匹配任意數(shù)目的字符(也可能是沒(méi)有)
          兩個(gè)星號(hào)**同樣是代表任意數(shù)目的字符,不同的是這個(gè)匹配可以穿越目錄邊界。例如 c:"a**"bar可以匹配c:"abc"bar,也可以匹配c:"am"cn"bar。
          問(wèn)號(hào)?匹配一個(gè)字符
          花括號(hào){}表明子模式的集合,例如{sun,moon,stars}可以匹配'sun','moon'或‘stars’;{temp*,tmp*}可以匹配以temp或tmp開(kāi)始的任意字符串。
          要匹配*,?或其他的特殊字符,可以使用轉(zhuǎn)義符"。例如""匹配單個(gè)的","?匹配問(wèn)號(hào)。
          方括號(hào)[]表示一組單獨(dú)的字符,當(dāng)使用了-的時(shí)候,也代表一個(gè)范圍的字符,例如:
          [aeiou]匹配任何單獨(dú)的元音字符,[0-9]匹配任意數(shù)字,[A-Z]匹配任意大寫(xiě)字母,[a-z,A-Z]匹配任意大寫(xiě)或小寫(xiě)字母。在方括號(hào)中,星號(hào)、問(wèn)號(hào)和"都只是表示它們自身,不再作為特殊符號(hào)。
          下面是一些例子:
          *.html匹配所有以.html結(jié)尾的字符串。
          ???匹配所有長(zhǎng)度為3的字符串
          *[0-9]*匹配所有包含有數(shù)字的字符串
          *.{html,htm,pdf}匹配所有以.html,.html或.pdf結(jié)尾的字符串
          a?*.java匹配所有以a開(kāi)頭,后面跟至少一個(gè)字符,然后以.java結(jié)尾的字符串。
          {foo*,*[0-9]*}匹配以foo開(kāi)頭的字符串或包含有數(shù)字的字符串。
          關(guān)于參數(shù)中的模式的使用,請(qǐng)參考FileSystem類(lèi)的getPathMatcher方法的幫助文檔。
          如果這種模式匹配仍然不能夠滿足需要,我們還可以使用正則表達(dá)式。



          Path會(huì)指向文件或者目錄,但是我們還不能確定這個(gè)文件或者目錄是否存在,是否可讀,是否可寫(xiě),是否可以執(zhí)行。要確定文件/目錄是否存在以及程序是否可以訪問(wèn)該文件/目錄,可以使用checkAccess(AccessMode...)方法。可選的AccessMode有:
              * READ – 檢查文件/目錄是否存在以及程序是否有權(quán)限讀該文件/目錄
              * WRITE – 檢查文件/目錄是否存在以及程序是否有權(quán)限寫(xiě)該文件/目錄
              * EXECUTE – 檢查文件/目錄是否存在以及程序在該文件/目錄上是否有執(zhí)行權(quán)限
          如果調(diào)用checkAccess的時(shí)候沒(méi)有傳入任何參數(shù),該方法只是檢查文件是否存在。
          下面的例子演示了怎樣驗(yàn)證文件是否存在以及程序是否有讀和執(zhí)行的權(quán)限。
          import static java.nio.file.AccessMode.*;
                
              Path file = ...;
              try {
                  file.checkAccess(READ, EXECUTE);
              } catch (IOException x) {
                  //Logic for error condition...
                  return;
              }

              //Logic for executable file...
          需要注意的是,當(dāng)checkAccess執(zhí)行完之后,文件的權(quán)限可能被其他的用戶(例如系統(tǒng)管理員)修改。這實(shí)際上是很多應(yīng)用程序都有的安全性的問(wèn)題。如果你感興趣,可以搜索TOCTTOU (time of check to time of use)。


          當(dāng)文件系統(tǒng)中存在符號(hào)鏈接的時(shí)候,可能兩個(gè)不同的路徑會(huì)指向同一個(gè)文件或目錄。方法isSamePath會(huì)比較兩個(gè)Path來(lái)檢查它們是否指向同一個(gè)文件/目錄。
              Path p1 = ...;
              Path p2 = ...;

              try {
                  if (p1.isSameFile(p2)) {
                      //Logic when the paths locate the same file
                  }
              } catch (IOException x) {
                  //Logic for error condition...
                  return;
              }
          posted @ 2010-03-29 10:02 afrag 閱讀(248) | 評(píng)論 (0)編輯 收藏
           
          Copyright © afrag Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 樟树市| 西吉县| 阳江市| 阜城县| 运城市| 德安县| 雅江县| 大荔县| 新晃| 清新县| 伊金霍洛旗| 尤溪县| 耒阳市| 平江县| 禹州市| 巫溪县| 汝南县| 奉化市| 阿勒泰市| 北辰区| 米易县| 勃利县| 中宁县| 会昌县| 大连市| 民乐县| 澄迈县| 手游| 东乌珠穆沁旗| 陇南市| 湖口县| 来宾市| 阿图什市| 济阳县| 宕昌县| 大化| 葵青区| 顺义区| 宝应县| 宜黄县| 洪泽县|