关键词搜索

源码搜索 ×
×

java之通过FileChannel实现文件复制

发布2018-06-10浏览3216次

详情内容

1、FileChanel介绍

Java NIO FileChannel是连接文件的通道,从文件中读取数据和将数据写入文件。Java NIO FileChannel类是NIO用于替代使用标准Java IO API读取文件的方法。

FileInputStream的getChannel方法获取的文件通道是只读的,当然通过FileOutputStream的getChannel的方法获取的文件通道是可写的

部分API

1)、truncate截断文件功能

  1. /**
  2. * Truncates the file underlying this channel to a given size. Any bytes
  3. * beyond the given size are removed from the file. If there are no bytes
  4. * beyond the given size then the file contents are unmodified.
  5. * <p>
  6. * If the file position is currently greater than the given size, then it is
  7. * set to the new size.
  8. *
  9. * @param size
  10. * the maximum size of the underlying file.
  11. * @throws IllegalArgumentException
  12. * if the requested size is negative.
  13. * @throws ClosedChannelException
  14. * if this channel is closed.
  15. * @throws NonWritableChannelException
  16. * if the channel cannot be written to.
  17. * @throws IOException
  18. * if another I/O error occurs.
  19. * @return this channel.
  20. */
  21. public abstract FileChannel truncate(long size) throws IOException;

2)、force()强制在内存中的数据刷新到硬盘中去

  1. /**
  2. * Requests that all updates to this channel are committed to the storage
  3. * device.
  4. * <p>
  5. * When this method returns, all modifications made to the platform file
  6. * underlying this channel have been committed if the file resides on a
  7. * local storage device. If the file is not hosted locally, for example on a
  8. * networked file system, then applications cannot be certain that the
  9. * modifications have been committed.
  10. * <p>
  11. * There are no assurances given that changes made to the file using methods
  12. * defined elsewhere will be committed. For example, changes made via a
  13. * mapped byte buffer may not be committed.
  14. * <p>
  15. * The <code>metadata</code> parameter indicates whether the update should
  16. * include the file's metadata such as last modification time, last access
  17. * time, etc. Note that passing <code>true</code> may invoke an underlying
  18. * write to the operating system (if the platform is maintaining metadata
  19. * such as last access time), even if the channel is opened read-only.
  20. *
  21. * @param metadata
  22. * {@code true} if the file metadata should be flushed in
  23. * addition to the file content, {@code false} otherwise.
  24. * @throws ClosedChannelException
  25. * if this channel is already closed.
  26. * @throws IOException
  27. * if another I/O error occurs.
  28. */
  29. public abstract void force(boolean metadata) throws IOException;

3)、transferFrom可以看出是拷贝从源的position位置的count 字节大小

  1. /**
  2. * Reads up to {@code count} bytes from {@code src} and stores them in this
  3. * channel's file starting at {@code position}. No bytes are transferred if
  4. * {@code position} is larger than the size of this channel's file. Less
  5. * than {@code count} bytes are transferred if there are less bytes
  6. * remaining in the source channel or if the source channel is non-blocking
  7. * and has less than {@code count} bytes immediately available in its output
  8. * buffer.
  9. * <p>
  10. * Note that this channel's position is not modified.
  11. *
  12. * @param src
  13. * the source channel to read bytes from.
  14. * @param position
  15. * the non-negative start position.
  16. * @param count
  17. * the non-negative number of bytes to transfer.
  18. * @return the number of bytes that are transferred.
  19. * @throws IllegalArgumentException
  20. * if the parameters are invalid.
  21. * @throws NonReadableChannelException
  22. * if the source channel is not readable.
  23. * @throws NonWritableChannelException
  24. * if this channel is not writable.
  25. * @throws ClosedChannelException
  26. * if either channel has already been closed.
  27. * @throws AsynchronousCloseException
  28. * if either channel is closed by other threads during this
  29. * operation.
  30. * @throws ClosedByInterruptException
  31. * if the thread is interrupted during this operation.
  32. * @throws IOException
  33. * if any I/O error occurs.
  34. */
  35. public abstract long transferFrom(ReadableByteChannel src, long position,
  36. long count) throws IOException;

 

 

 

 

2、复制文件常用方法

1、通过普通输入输出流复制文件

  1. public void copyFile(File srcFile, File dstFile) throws FileNotFoundException {
  2. InputStream inputStream = null;
  3. OutputStream outputStream = null;
  4. try {
  5. inputStream = new BufferedInputStream(new FileInputStream(srcFile));
  6. outputStream = new BufferedOutputStream(new FileOutputStream(dstFile));
  7. byte[] bytes = new byte[1024];
  8. int i;
  9. //读取到输入流数据,然后写入到输出流中去,实现复制
  10. while ((i = inputStream.read(bytes)) != -1) {
  11. outputStream.write(bytes, 0, i);
  12. }
  13. } catch (Exception e) {
  14. e.printStackTrace();
  15. } finally {
  16. try {
  17. if (inputStream != null)
  18. inputStream.close();
  19. if (outputStream != null)
  20. outputStream.close();
  21. } catch (IOException e) {
  22. e.printStackTrace();
  23. }
  24. }
  25. }

 

2、通过 FileChannel复制文件

 

  1. public void copyFile(File srcFile, File dstFile) throws IOException {
  2. if (srcFile == null || !srcFile.exists()) {
  3. return;
  4. }
  5. if (dstFile == null || !dstFile.exists()) {
  6. return;
  7. }
  8. FileInputStream fileIns = null;
  9. FileOutputStream fileOuts = null;
  10. FileChannel source = null;
  11. FileChannel destination = null;
  12. try {
  13. fileIns = new FileInputStream(srcFile);
  14. fileOuts = new FileOutputStream(dstFile);
  15. source = fileIns.getChannel();
  16. destination = fileOuts.getChannel();
  17. destination.transferFrom(source, 0, source.size());
  18. } catch (Exception e) {
  19. e.printStackTrace();
  20. } finally {
  21. if (fileIns != null)
  22. fileIns.close();
  23. if (fileOuts != null)
  24. fileOuts.close();
  25. if (source != null)
  26. source.close();
  27. if (destination != null)
  28. destination.close();
  29. }
  30. }

 

 

 

3、总结

一般复制使用输入输出流进行操作,用源文件创建出一个输入流,用目标文件创建出一个输出流,把输入流的数据读取写入到输出流,用fileChannel,直接连接输入输出流的文件通道,将数据直接写入到目标文件中,效率很高,尤其是复制文件比较大的时候,我们一般采用fileChannel复制文件。

 

 

 

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载