您好,登錄后才能下訂單哦!
本篇內(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ì)量的實用文章!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。