版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35241080/article/details/82557776
一、使用通道完成本地文件复制
1.利用通道完成文件的复制(非直接缓冲区)
//利用通道完成数据传输(非直接缓冲区)
@Test
public void test1() {
//1.获取通道
FileInputStream fis = null;
FileOutputStream fos = null;
FileChannel fisChannel = null;
FileChannel fosChannel = null;
//2.获取缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
try {
fis = new FileInputStream("d:/tomcat.zip");
fos = new FileOutputStream("d:/tomcat2.zip");
fisChannel = fis.getChannel();
fosChannel = fos.getChannel();
//3.读取通道中的数据至缓存区
while(fisChannel.read(buffer)!=-1){
//切换读写数据模式
buffer.flip();
//4.将缓存中的数据写出到指定文件
fosChannel.write(buffer);
buffer.clear();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fisChannel!=null){
try {
fisChannel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fosChannel!=null){
try {
fosChannel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(fis!=null){
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
2.内存映射文件
//使用直接缓冲区完成文件的复制(内存映射文件)
@Test
public void test2() throws IOException{
long start = System.currentTimeMillis();
FileChannel inChannel = FileChannel.open(Paths.get("d:/1.mkv"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("d:/2.mkv"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
//内存映射文件
MappedByteBuffer inMappedBuf = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
MappedByteBuffer outMappedBuf = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
//直接对缓冲区进行数据的读写操作
byte[] dst = new byte[inMappedBuf.limit()];
inMappedBuf.get(dst);
outMappedBuf.put(dst);
inChannel.close();
outChannel.close();
long end = System.currentTimeMillis();
System.out.println("耗费时间为:" + (end - start));
}
3.通道之间的数据传输(直接缓冲区)
从哪里来–到哪里去
@Test
public void test3() throws IOException{
FileChannel inChannel = FileChannel.open(Paths.get("d:/tomcat.zip"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("d:/tomcat4.zip"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
//去哪里:inChannel从0-末尾,到outChannel输出管道中去
// inChannel.transferTo(0, inChannel.size(), outChannel);
//从哪里来:outChannel输出管道中的数据,是从inChannel输入管道中0-末尾来的数据
outChannel.transferFrom(inChannel, 0, inChannel.size());
inChannel.close();
outChannel.close();
}
4.通道之间的数据传输(直接缓冲区)Files.newByteChannel();
//通道之间的数据传输(直接缓冲区)Files.newByteChannel();
@Test
public void test4() throws IOException{
// import java.nio.channels.SeekableByteChannel;
FileChannel fis = (FileChannel) Files.newByteChannel(Paths.get("d:/tomcat.zip"), StandardOpenOption.READ);
FileChannel fos = (FileChannel) Files.newByteChannel(Paths.get("d:/tomcat9.zip"), StandardOpenOption.WRITE,StandardOpenOption.CREATE,StandardOpenOption.READ);
// fis.transferTo(0, fis.size(), fos);
fos.transferFrom(fis, 0, fis.size());
fis.close();
fos.close();
}
二、常用类型介绍
1.FileChannel 的常用方法
int read(ByteBuffer dst) // 从 Channel 中读取数据到 ByteBuffer
long read(ByteBuffer[] dsts) // 将 Channel 中的数据“分散”到 ByteBuffer[]
int write(ByteBuffer src) // 将 ByteBuffer 中的数据写入到 Channel
long write(ByteBuffer[] srcs) // 将 ByteBuffer[] 中的数据“聚集”到 Channel
long position() //返回此通道的文件位置
FileChannel position(long p) //设置此通道的文件位置
long size() //返回此通道的文件的当前大小
FileChannel truncate(long s) //将此通道的文件截取为给定大小
void force(boolean metaData) //强制将所有对此通道的文件更新写入到存储设备中
public static FileChannel open(Path path, OpenOption... options)//打开文件设置参数,获取通道
2.StandardOpenOption数据类型
public enum StandardOpenOption implements OpenOption{
//读文件模式
READ,
//写文件模式
WRITE,
//追加数据到某个文件中,不能与READ同时使用,文件必须存在,不存在则报异常-java.nio.file.NoSuchFileException
APPEND,
/**
* If the file already exists and it is opened for {@link #WRITE}
* access, then its length is truncated to 0. This option is ignored
* if the file is opened only for {@link #READ} access.
*/
TRUNCATE_EXISTING,
//新建文件,一般在写出数据到某个文件时用到,如果文件存在则覆盖
CREATE,
/**创建一个文件,如果文件存在则包异常--java.nio.file.FileAlreadyExistsException
* Create a new file, failing if the file already exists.
* The check for the existence of the file and the creation of the file
* if it does not exist is atomic with respect to other file system
* operations.
*/
CREATE_NEW,
//----以下未用到,留待以后使用
DELETE_ON_CLOSE,
/**
* Sparse file. When used with the {@link #CREATE_NEW} option then this
* option provides a <em>hint</em> that the new file will be sparse. The
* option is ignored when the file system does not support the creation of
* sparse files.
*/
SPARSE,
/**
* Requires that every update to the file's content or metadata be written
* synchronously to the underlying storage device.
*
* @see <a href="package-summary.html#integrity">Synchronized I/O file integrity</a>
*/
SYNC,
/**
* Requires that every update to the file's content be written
* synchronously to the underlying storage device.
*
* @see <a href="package-summary.html#integrity">Synchronized I/O file integrity</a>
*/
DSYNC;
}
3.Path
Paths 提供的 get() 方法用来获取 Path 对象:
Path get(String first, String … more) : 用于将多个字符串串连成路径。
Path 常用方法:
boolean endsWith(String path) : 判断是否以 path 路径结束
boolean startsWith(String path) : 判断是否以 path 路径开始
boolean isAbsolute() : 判断是否是绝对路径
Path getFileName() : 返回与调用 Path 对象关联的文件名
Path getName(int idx) : 返回的指定索引位置 idx 的路径名称
int getNameCount() : 返回Path 根目录后面元素的数量
Path getParent() :返回Path对象包含整个路径,不包含 Path 对象指定的文件路径
Path getRoot() :返回调用 Path 对象的根路径
Path resolve(Path p) :将相对路径解析为绝对路径
Path toAbsolutePath() : 作为绝对路径返回调用 Path 对象
String toString() : 返回调用 Path 对象的字符串表示形式
public static Path get(String first, String... more) {
return FileSystems.getDefault().getPath(first, more);
}
//根据文件地址获取path对象
public static Path get(URI uri) {
String scheme = uri.getScheme();
if (scheme == null)
throw new IllegalArgumentException("Missing scheme");
// check for default provider to avoid loading of installed providers
if (scheme.equalsIgnoreCase("file"))
return FileSystems.getDefault().provider().getPath(uri);
// try to find provider
for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
if (provider.getScheme().equalsIgnoreCase(scheme)) {
return provider.getPath(uri);
}
}
throw new FileSystemNotFoundException("Provider \"" + scheme + "\" not installed");
}
4.Files常用方法:
Path copy(Path src, Path dest, CopyOption … how) : 文件的复制
Path createDirectory(Path path, FileAttribute<?> … attr) : 创建一个目录
Path createFile(Path path, FileAttribute<?> … arr) : 创建一个文件
void delete(Path path) : 删除一个文件
Path move(Path src, Path dest, CopyOption…how) : 将 src 移动到 dest 位置
long size(Path path) : 返回 path 指定文件的大小
**Files常用方法:用于判断**
boolean exists(Path path, LinkOption … opts) : 判断文件是否存在
boolean isDirectory(Path path, LinkOption … opts) : 判断是否是目录
boolean isExecutable(Path path) : 判断是否是可执行文件
boolean isHidden(Path path) : 判断是否是隐藏文件
boolean isReadable(Path path) : 判断文件是否可读
boolean isWritable(Path path) : 判断文件是否可写
boolean notExists(Path path, LinkOption … opts) : 判断文件是否不存在
**Files常用方法:用于操作内容**
SeekableByteChannel newByteChannel(Path path, OpenOption…how) : 获取与指定文件的连接,how 指定打开方式。
DirectoryStream newDirectoryStream(Path path) : 打开 path 指定的目录
InputStream newInputStream(Path path, OpenOption…how):获取 InputStream 对象
OutputStream newOutputStream(Path path, OpenOption…how) : 获取 OutputStream 对象