afrag  
          記錄學習和成長的歷程
          日歷
          <2010年4月>
          28293031123
          45678910
          11121314151617
          18192021222324
          2526272829301
          2345678
          統計
          • 隨筆 - 9
          • 文章 - 5
          • 評論 - 2
          • 引用 - 0

          導航

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          文章檔案

          搜索

          •  

          積分與排名

          • 積分 - 10198
          • 排名 - 2381

          最新評論

          閱讀排行榜

          評論排行榜

           

          2010年4月5日

          轉自 開發者的天空

          本文中我們來討論在NIO2中怎樣創建文件、讀取文件和寫文件。NIO2提供了多種創建 文件的方法,使得我們在創建文件的時候就可以指定文件的某些初始屬性。例如在支持POSIX的文件系統上指定文件的所有者,訪問權限等。關于文件的屬性, 請看上一篇文章Java SE 7新特性之文件操作(5) - 管理元數據
          創建文件
          可以調用createFile(FileAttribute<?>)方法創建一個空文件。該方法的參數就是文件的初始屬性。下面的例子是怎樣 在創建文件的時候賦予該文件某些權限的屬性:
          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
          }
          如 果在調用該方法的時候沒有傳入任何參數,那么創建的文件將具有缺省的文件屬性。下面的代碼創建了一個具有缺省文件屬性的文件:
          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);
          }
          如 果要創建的文件已經存在,該方法會拋出異常。
          注意在調用createFile方法時,檢查文件是否存在和創建具有特定的屬性的文件是在同一個原子操作中。
          還可以使用newOutputSteam方法來創建文件,在本文的后面我們會講到怎樣使用newOutputStream方法來創建文件。
          通過Stream I/O讀文件
          我們可以通過newInputStream(OpenOption...)方法打開和讀取文件。這個方法返回一個unbuffered輸入流(input stream),我們可以用它來從文件中讀取字節內容。
          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();
          }
          注 意該方法接受可變個數的參數,參數類型為OpenOption,指定了文件怎樣打開。如果不傳入參數,則使用默認的READ方式打開。READ方式是所有 的實現都支持的方式。有一些實現也支持其他的打開方式。
          如果傳入的OpenOption或其組合不正確,會拋出異常。如果程序沒有讀權限或I/O錯誤,也會拋出異常。
          Creating and Writing a File by Using Stream I/O
          使用Stream I/O來創建和寫文件
          我們可以使用newOutputStream方法來創建文件、擴展文件或覆蓋已有文件。這個方法為了寫文件而打開或創建文件,該方法返回一個 unbuffered的輸出流(output stream)。newOutputStream方法有兩種形式:

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

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

          • WRITE –為了寫訪問而打開該文件.
          • APPEND – 將新數據擴展在文件的末尾。該選項和WRITE或CREATE選項一起使用。
          • TRUNCATE_EXISTING – 將文件截斷為0字節長. 該選項和WRITE選項一起使用來覆蓋原有文件。
          • CREATE_NEW – 創建一個新的文件。如果原來的文件存在這拋出異常。
          • CREATE – 如果原文件存在這打開它,否則創建新的文件。
          • DELETE_ON_CLOSE – 當Stream關閉時刪除該文件。這個選項對臨時文件比較有用。
          • SPARSE – 表明新創建的文件是Sparse文件. 關于Sparse文件的具體信息請看http://space.itpub.net/8242091/viewspace-619756
          • SYNC – 保持該文件(包括內容和元數據)與底層存儲設備同步。
          • DSYNC – 保持文件內容與底層存儲設備同步。

          如果沒有指定OpenOption,該方法的行為是:如果文件不存在,則創建新文件;如果文件存在,那么截斷它。也就是說缺省的選擇是CREATE和 TRUNCATE_EXISTING選項的組合。
          下面的代碼打開一個日志文件,如果文件不存在,則創建一個新文件。如果文件 存在,這將新的內容擴展到文件尾部。
          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來讀寫文件
          Stream I/O每次讀取一個字符,Channel I/O每次讀取一個緩沖塊的數據。ByteChannel接口提供了基本的讀寫功能。SeekableByteChannel擴展了 ByteChannel并提供了維護一個channel中的位置并改變該位置的能力。SeekableByteChannel還支持截斷文件和查詢文件大 小的功能。
          移動到文件中不同的位置,從該位置開始讀或寫的能力使我們可以隨機訪問文件。有兩種形式的 newByteChannel方法可以用來讀或寫文件,這兩種形式和newOutputStream方法一樣。

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

          這兩個方法都允許指定OpenOption,newOutputStream所支持的選擇這里也支持,而且這里還支持另外一個選項READ,因為 SeekableByteChannel既支持讀也支持寫。
          如果選項是READ,那么該channel就是為了讀訪問打開。如果選項是WRITE或APPEND,則該channel就是為了寫訪問打開。如果沒有指 定,該channel默認是為了讀打開。
          下面的代碼從文件中讀取內容并輸出到控制臺上:
          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的文件系統編寫的。這段代碼創建一個新的日志文件或者擴展原有的日志文件,該日志文件創建時指定了訪問權限 (所有者有讀寫權限,同組用戶只有讀權限,其他用戶沒有讀權限)。
          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 閱讀(498) | 評論 (0)編輯 收藏
           
          Copyright © afrag Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 清苑县| 湟源县| 建湖县| 酒泉市| 夏河县| 巫山县| 无棣县| 万山特区| 咸丰县| 微博| 稻城县| 壤塘县| 亚东县| 子洲县| 加查县| 固原市| 宁夏| 错那县| 庆城县| 云南省| 大余县| 葫芦岛市| 抚宁县| 海晏县| 惠来县| 西城区| 松滋市| 寿阳县| 康乐县| 泰来县| 云浮市| 山西省| 武汉市| 西乌| 平顶山市| 游戏| 浦东新区| 金川县| 会理县| 通渭县| 延安市|