1、FileChanel介绍
Java NIO FileChannel是连接文件的通道,从文件中读取数据和将数据写入文件。Java NIO FileChannel类是NIO用于替代使用标准Java IO API读取文件的方法。
FileInputStream的getChannel方法获取的文件通道是只读的,当然通过FileOutputStream的getChannel的方法获取的文件通道是可写的
部分API
1)、truncate截断文件功能
- /**
- * 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()强制在内存中的数据刷新到硬盘中去
- /**
- * 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 字节大小
- /**
- * 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、复制文件常用方法
1、通过普通输入输出流复制文件
- 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;
- //读取到输入流数据,然后写入到输出流中去,实现复制
- 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复制文件
- 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、总结
一般复制使用输入输出流进行操作,用源文件创建出一个输入流,用目标文件创建出一个输出流,把输入流的数据读取写入到输出流,用fileChannel,直接连接输入输出流的文件通道,将数据直接写入到目标文件中,效率很高,尤其是复制文件比较大的时候,我们一般采用fileChannel复制文件。