java之通過FileChannel實(shí)現(xiàn)文件復(fù)制
1、FileChanel介紹
Java NIO FileChannel是連接文件的通道,從文件中讀取數(shù)據(jù)和將數(shù)據(jù)寫入文件。Java NIO FileChannel類是NIO用于替代使用標(biāo)準(zhǔn)Java IO API讀取文件的方法。
FileInputStream的getChannel方法獲取的文件通道是只讀的,當(dāng)然通過FileOutputStream的getChannel的方法獲取的文件通道是可寫的
部分API
1)、truncate截?cái)辔募δ?br>
/**
* Truncates the file underlying this channel to a given size. Any bytes
* beyond the given size are removed from the file. If there are no bytes
* beyond the given size then the file contents are unmodified.
* <p>
* If the file position is currently greater than the given size, then it is
* set to the new size.
*
* @param size
* the maximum size of the underlying file.
* @throws IllegalArgumentException
* if the requested size is negative.
* @throws ClosedChannelException
* if this channel is closed.
* @throws NonWritableChannelException
* if the channel cannot be written to.
* @throws IOException
* if another I/O error occurs.
* @return this channel.
*/
public abstract FileChannel truncate(long size) throws IOException;
2)、force()強(qiáng)制在內(nèi)存中的數(shù)據(jù)刷新到硬盤中去
/**
* Requests that all updates to this channel are committed to the storage
* device.
* <p>
* When this method returns, all modifications made to the platform file
* underlying this channel have been committed if the file resides on a
* local storage device. If the file is not hosted locally, for example on a
* networked file system, then applications cannot be certain that the
* modifications have been committed.
* <p>
* There are no assurances given that changes made to the file using methods
* defined elsewhere will be committed. For example, changes made via a
* mapped byte buffer may not be committed.
* <p>
* The <code>metadata</code> parameter indicates whether the update should
* include the file's metadata such as last modification time, last access
* time, etc. Note that passing <code>true</code> may invoke an underlying
* write to the operating system (if the platform is maintaining metadata
* such as last access time), even if the channel is opened read-only.
*
* @param metadata
* {@code true} if the file metadata should be flushed in
* addition to the file content, {@code false} otherwise.
* @throws ClosedChannelException
* if this channel is already closed.
* @throws IOException
* if another I/O error occurs.
*/
public abstract void force(boolean metadata) throws IOException;
3)、transferFrom可以看出是拷貝從源的position位置的count 字節(jié)大小
/**
* Reads up to {@code count} bytes from {@code src} and stores them in this
* channel's file starting at {@code position}. No bytes are transferred if
* {@code position} is larger than the size of this channel's file. Less
* than {@code count} bytes are transferred if there are less bytes
* remaining in the source channel or if the source channel is non-blocking
* and has less than {@code count} bytes immediately available in its output
* buffer.
* <p>
* Note that this channel's position is not modified.
*
* @param src
* the source channel to read bytes from.
* @param position
* the non-negative start position.
* @param count
* the non-negative number of bytes to transfer.
* @return the number of bytes that are transferred.
* @throws IllegalArgumentException
* if the parameters are invalid.
* @throws NonReadableChannelException
* if the source channel is not readable.
* @throws NonWritableChannelException
* if this channel is not writable.
* @throws ClosedChannelException
* if either channel has already been closed.
* @throws AsynchronousCloseException
* if either channel is closed by other threads during this
* operation.
* @throws ClosedByInterruptException
* if the thread is interrupted during this operation.
* @throws IOException
* if any I/O error occurs.
*/
public abstract long transferFrom(ReadableByteChannel src, long position,
long count) throws IOException;
2、復(fù)制文件常用方法
1、通過普通輸入輸出流復(fù)制文件
public void copyFile(File srcFile, File dstFile) throws FileNotFoundException {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream(srcFile));
outputStream = new BufferedOutputStream(new FileOutputStream(dstFile));
byte[] bytes = new byte[1024];
int i;
//讀取到輸入流數(shù)據(jù),然后寫入到輸出流中去,實(shí)現(xiàn)復(fù)制
while ((i = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, i);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null)
inputStream.close();
if (outputStream != null)
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2、通過 FileChannel復(fù)制文件
public void copyFile(File srcFile, File dstFile) throws IOException {
if (srcFile == null || !srcFile.exists()) {
return;
}
if (dstFile == null || !dstFile.exists()) {
return;
}
FileInputStream fileIns = null;
FileOutputStream fileOuts = null;
FileChannel source = null;
FileChannel destination = null;
try {
fileIns = new FileInputStream(srcFile);
fileOuts = new FileOutputStream(dstFile);
source = fileIns.getChannel();
destination = fileOuts.getChannel();
destination.transferFrom(source, 0, source.size());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fileIns != null)
fileIns.close();
if (fileOuts != null)
fileOuts.close();
if (source != null)
source.close();
if (destination != null)
destination.close();
}
}
3、總結(jié)
一般復(fù)制使用輸入輸出流進(jìn)行操作,用源文件創(chuàng)建出一個(gè)輸入流,用目標(biāo)文件創(chuàng)建出一個(gè)輸出流,把輸入流的數(shù)據(jù)讀取寫入到輸出流,用fileChannel,直接連接輸入輸出流的文件通道,將數(shù)據(jù)直接寫入到目標(biāo)文件中,效率很高,尤其是復(fù)制文件比較大的時(shí)候,我們一般采用fileChannel復(fù)制文件。
作者:chen.yu
深信服三年半工作經(jīng)驗(yàn),目前就職游戲廠商,希望能和大家交流和學(xué)習(xí),
微信公眾號(hào):編程入門到禿頭 或掃描下面二維碼
零基礎(chǔ)入門進(jìn)階人工智能(鏈接)