溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java如何將內(nèi)存數(shù)組流的數(shù)據(jù)寫入文件流中

發(fā)布時間:2022-01-06 17:01:18 來源:億速云 閱讀:149 作者:iii 欄目:互聯(lián)網(wǎng)科技

本篇內(nèi)容介紹了“java如何將內(nèi)存數(shù)組流的數(shù)據(jù)寫入文件流中”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

在 java 字節(jié)流入門(文件流)中,我們介紹了 FileOutputStream(FOS) 和 RandomAccessFile(RAF) 兩種寫文件的方式。那么,當我們在內(nèi)存中使用 ByteArrayOutputStream(BAOS) 維護數(shù)據(jù)時,如何利用 FOS 和 RAF 寫文件呢,本文介紹四種方法。

準備工作:

   private static final Path path = Paths.get("src", "main", "resources", "test.myfile");
   private static final File file = path.toFile();
   private static int size = 1024*1024*800;
   private static byte[] b1 = new byte[size];
   private static ByteArrayOutputStream out = new ByteArrayOutputStream();

并將 b1 寫入 out 中

out.write(b1);

writeTo寫入FOS

首先,BAOS 有一個方法叫 writeTo(),這個方法可以將 BAOS 中的數(shù)據(jù)直接寫入另一個字節(jié)輸出流中。更準確的說法是,使用另一個字節(jié)輸出流的 write() 方法將 BAOS 中的數(shù)據(jù)寫出去。這里 BAOS 就和一個字節(jié)數(shù)組是等價的。

   /**
    * Writes the complete contents of this byte array output stream to
    * the specified output stream argument, as if by calling the output
    * stream's write method using <code>out.write(buf, 0, count)</code>.
    *
    * @param      out   the output stream to which to write the data.
    * @exception  IOException  if an I/O error occurs.
    */
   public synchronized void writeTo(OutputStream out) throws IOException {
       out.write(buf, 0, count);
   }

因為 FOS 本身就是 OutputStream,所以可以直接將 BAOS 中的數(shù)據(jù)通過 writeTo() 寫入 FOS 中。

// 將 BAOS 中的數(shù)據(jù)寫入 FileOutputStream
   private static void writeToFOS() throws IOException {
       if(file.exists())
           file.delete();
       // 將 ByteArrayOutputStream 緩存的數(shù)據(jù)寫入 FileOutputStream 中,即寫入文件中
       FileOutputStream fileOutputStream = new FileOutputStream(file, false);

       long time = System.currentTimeMillis();
       out.writeTo(fileOutputStream);
       fileOutputStream.close();
       time = System.currentTimeMillis() - time;
       System.out.println("將 "+ size + " 個字節(jié)寫入 FOS 耗時:" + time + "ms");
       file.delete();
   }

writeTo寫入RAF

由于 RandomAccessFile 不是標準的 OutputStream,所以沒法直接用 writeTo() 方法實現(xiàn)。那如何將 BAOS 中的數(shù)據(jù)寫入 RandomAccessFile 呢?

解決方案是:把 RandomAccessFile 包裝成一個 OutputStream。我們實現(xiàn)一個 自定義的 OutputStream,繼承 OutputStream,并用 RAF 的三種寫方法覆蓋 OutputStream 的原有寫方法。

class MyRandomAccessFileOutputStream extends OutputStream {

   private RandomAccessFile raf;

   public MyRandomAccessFileOutputStream(RandomAccessFile raf) {
       this.raf = raf;
   }

   @Override
   public void write(int b) throws IOException {
       raf.write(b);
   }

   @Override
   public void write(byte b[]) throws IOException {
       raf.write(b);
   }

   @Override
   public void write(byte b[], int off, int len) throws IOException {
       raf.write(b, off, len);
   }

   public void seek(long pos) throws IOException {
       raf.seek(pos);
   }

   public long length() throws IOException {
       return raf.length();
   }

   @Override
   public void close() throws IOException {
       raf.close();
   }

}

接下來,就可以開心的把 RandomAccessFile 當 OutputStream 用了。

// 將 BAOS 中的數(shù)據(jù)寫入 MyRandomAccessFileOutputStream
   private static void writeToMyRaf() throws IOException {
       if(file.exists())
           file.delete();
       RandomAccessFile raf = new RandomAccessFile(file, "rw");
       MyRandomAccessFileOutputStream myraf = new MyRandomAccessFileOutputStream(raf);

       long time = System.currentTimeMillis();
       out.writeTo(myraf);
       myraf.close();
       time = System.currentTimeMillis() - time;
       System.out.println("將 "+ size + " 個字節(jié)寫入 MyRaf 耗時:" + time + "ms");
       file.delete();
   }

Copy寫入FOS

大家記不記得 BAOS 還有個 toByteArray() 方法可以將其中的內(nèi)容返回一個 byte 數(shù)組。其實現(xiàn)調(diào)用了 Arrays.copyOf() 方法,這里記做 copy 。

然后回想,其實各種流都有一個 write(byte[]) 方法,所以你們知道我想干嘛了嗎,嗯,很粗暴的實現(xiàn)方式,上代碼。

// 將 BAOS 中的數(shù)據(jù) copy 寫入 FileOutputStream
   private static void copyToFOS() throws IOException {
       if(file.exists())
           file.delete();
       // 將 ByteArrayOutputStream 緩存的數(shù)據(jù)寫入 FileOutputStream 中,即寫入文件中
       FileOutputStream fileOutputStream = new FileOutputStream(file, false);

       long time = System.currentTimeMillis();
       fileOutputStream.write(out.toByteArray());
       fileOutputStream.close();
       time = System.currentTimeMillis() - time;
       System.out.println("將 "+ size + " 個字節(jié) copy 寫入 FOS 耗時:" + time + "ms");
       file.delete();
   }

Copy寫入RAF

同樣的,RandomAccessFile 也有 write(byte[]) 方法,所以。。。繼續(xù)上代碼:

 

// 將 BAOS 中的數(shù)據(jù) copy 寫入 RandomAccessFile
   private static void copyToRaf() throws IOException {
       if(file.exists())
           file.delete();
       RandomAccessFile raf = new RandomAccessFile(file, "rw");

       long time = System.currentTimeMillis();
       raf.write(out.toByteArray());
       raf.close();
       time = System.currentTimeMillis() - time;
       System.out.println("將 "+ size + " 個字節(jié) copy 寫入 Raf 耗時:" + time + "ms");
       file.delete();
   }

接下來我們比較一下這四種方式的速度:

實驗對比

寫 800M數(shù)據(jù)。將 RAF 包裝成 OutputStream 和 FileOutputStream 的效率差不多。對于兩種文件流的寫入方法,writeTo 總是比 copy 寫入要快。畢竟 copy 多了一步拷貝,而且會占用額外內(nèi)存。

所以不管哪種文件流,用 BAOS 的 writeTo() 都是最好的。

將 838860800 個字節(jié)寫入 FOS 耗時:1413ms
將 838860800 個字節(jié) copy 寫入 FOS 耗時:2092ms
將 838860800 個字節(jié)寫入 MyRaf 耗時:1452ms
將 838860800 個字節(jié) copy 寫入 Raf 耗時:2203ms

“java如何將內(nèi)存數(shù)組流的數(shù)據(jù)寫入文件流中”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI