NIO

 

NIO

  • channel:可以理解为一个通道。channel把文件中数据映射到Buffer中。然后channel操作Buffer进行读写操作
  • Buffer: 就是一个容器,channel进行读写的容器工具,另外,Buffer本身也可以完成读写操作

使用Buffer

  • 从0开始就有数据
  • capacity:容量。
  • limit:第一个不应该被操作的缓冲区索引位置。limit之后不可读写
  • position: 当前可操作的位置。大小是已经读到数据大小
  • mark:自游标,可以把position置为mark
  • 创建Buffer后position初始值为0,limit为capacity
  • 在Buffer中每读取一个数据,position+1.
  • flip():读取数据完成以后,调用 flip()方法,position变为0,limit变为position。调用 flip()方法为输出数据做好准备(封闭包)
  • clear():该方法不会清空缓冲区,只将position变为0,limit变为capacity。为再次输入做好准备
  • put()和get()方法

  • 相对操作: Buffer从position的位置进行读写 position+1    get();

  • 绝对操作:Buffer使用索引位置进行读写  ,根据索引操作不会影响position的位置          get(int x);

 

使用Channel

  • 程序只能通过Buffe与Channel交换数据
  • 常用方法:map() read() write()系列方法
  • 获取方法: 节点流.getChannel(); 
  • 实例复制文件内容到a.txt 并打印内容(映射整个文件)
  • public class FileChannelTest
    {
    	public static void main(String[] args)
    	{
    		File f = new File("FileChannelTest.java");
    		try(
    			// 创建FileInputStream,以该文件输入流创建FileChannel
    			FileChannel inChannel = new FileInputStream(f).getChannel();
    			// 以文件输出流创建FileBuffer,用以控制输出
    			FileChannel outChannel = new FileOutputStream("a.txt")
    				.getChannel())
    		{
    			// 将FileChannel里的全部数据映射成ByteBuffer
    			MappedByteBuffer buffer = inChannel.map(FileChannel
    				.MapMode.READ_ONLY , 0 , f.length());   // ①
    			// 使用GBK的字符集来创建解码器
    			Charset charset = Charset.forName("GBK");
    			// 直接将buffer里的数据全部输出
    			outChannel.write(buffer);     // ②
    			// 再次调用buffer的clear()方法,复原limit、position的位置
    			buffer.clear();
    			// 创建解码器(CharsetDecoder)对象
    			CharsetDecoder decoder = charset.newDecoder();
    			// 使用解码器将ByteBuffer转换成CharBuffer
    			CharBuffer charBuffer =  decoder.decode(buffer);
    			// CharBuffer的toString方法可以获取对应的字符串
    			System.out.println(charBuffer);
    		}
    		catch (IOException ex)
    		{
    			ex.printStackTrace();
    		}
    	}
    }

     

  • 复制a.txt文件内容追加到a.txt末尾(使用RandomAccessFile对象获取Channel)
  • public class RandomFileChannelTest
    {
    	public static void main(String[] args)
    		throws IOException
    	{
    		File f = new File("a.txt");
    		try(
    			// 创建一个RandomAccessFile对象
    			RandomAccessFile raf = new RandomAccessFile(f, "rw");
    			// 获取RandomAccessFile对应的Channel
    			FileChannel randomChannel = raf.getChannel())
    		{
    			// 将Channel中所有数据映射成ByteBuffer
    			ByteBuffer buffer = randomChannel.map(FileChannel
    				.MapMode.READ_ONLY, 0 , f.length());
    			// 把Channel的记录指针移动到最后
    			randomChannel.position(f.length());
    			// 将buffer中所有数据输出
    			randomChannel.write(buffer);
    		}
    	}
    }

    映射文件的一部分,(每次取一部分)

  • public class ReadFile
    {
    	public static void main(String[] args)
    		throws IOException
    	{
    		try(
    			// 创建文件输入流
    			FileInputStream fis = new FileInputStream("ReadFile.java");
    			// 创建一个FileChannel
    			FileChannel fcin = fis.getChannel())
    		{
    			// 定义一个ByteBuffer对象,用于重复取水
    			ByteBuffer bbuff = ByteBuffer.allocate(256);
    			// 将FileChannel中数据放入ByteBuffer中
    			while( fcin.read(bbuff) != -1 )
    			{
    				// 锁定Buffer的空白区
    				bbuff.flip();
    				// 创建Charset对象
    				Charset charset = Charset.forName("GBK");
    				// 创建解码器(CharsetDecoder)对象
    				CharsetDecoder decoder = charset.newDecoder();
    				// 将ByteBuffer的内容转码
    				CharBuffer cbuff = decoder.decode(bbuff);
    				System.out.print(cbuff);
    				// 将Buffer初始化,为下一次读取数据做准备
    				bbuff.clear();
    			}
    		}
    	}
    }

     

字符集与和Charset

  • 没啥东西贴个代码好了
  • public class CharsetTest
    {
    	public static void main(String[] args)
    	{
    		// 获取Java支持的全部字符集
    		SortedMap<String,Charset>  map = Charset.availableCharsets();
    		for (String alias : map.keySet())
    		{
    			// 输出字符集的别名和对应的Charset对象
    			System.out.println(alias + "----->"
    				+ map.get(alias));
    		}
    	}
    }
    public class CharsetTransform
    {
    	public static void main(String[] args)
    		throws Exception
    	{
    		// 创建简体中文对应的Charset
    		Charset cn = Charset.forName("GBK");
    		// 获取cn对象对应的编码器和解码器
    		CharsetEncoder cnEncoder = cn.newEncoder();
    		CharsetDecoder cnDecoder = cn.newDecoder();
    		// 创建一个CharBuffer对象
    		CharBuffer cbuff = CharBuffer.allocate(8);
    		cbuff.put('孙');
    		cbuff.put('悟');
    		cbuff.put('空');
    		cbuff.flip();
    		// 将CharBuffer中的字符序列转换成字节序列
    		ByteBuffer bbuff = cnEncoder.encode(cbuff);
    		// 循环访问ByteBuffer中的每个字节
    		for (int i = 0; i < bbuff.capacity() ; i++)
    		{
    			System.out.print(bbuff.get(i) + " ");
    		}
    		// 将ByteBuffer的数据解码成字符序列
    		System.out.println("\n" + cnDecoder.decode(bbuff));
    	}
    }

    可以不获取CharsetEncoder对象,Charset对象可以直接进行编码或解码

文件锁

  • lock();阻塞式,若无法得到锁,将会阻塞线程
  • trylock():非阻塞式,若无法得到锁,返回null
  • public class FileLockTest
    {
    	public static void main(String[] args)
    		throws Exception
    	{
    
    		try(
    			// 使用FileOutputStream获取FileChannel
    			FileChannel channel = new FileOutputStream("a.txt")
    				.getChannel())
    		{
    			// 使用非阻塞式对指定文件加锁
    			FileLock lock = channel.tryLock();
    			// 暂停10s
    			Thread.sleep(10000);
    			// 释放锁
    			lock.release();
    		}
    	}
    }

    NIO2

  • 核心API: Path Paths(工具) Files (工具)
  • path使用
  • public class PathTest
    {
    	public static void main(String[] args)
    		throws Exception
    	{
    		// 以当前路径来创建Path对象
    		Path path = Paths.get(".");
    		System.out.println("path里包含的路径数量:"
    			+ path.getNameCount());
    		System.out.println("path的根路径:" + path.getRoot());
    		// 获取path对应的绝对路径。
    		Path absolutePath = path.toAbsolutePath();
    		System.out.println(absolutePath);
    		// 获取绝对路径的根路径
    		System.out.println("absolutePath的根路径:"
    			+ absolutePath.getRoot());
    		// 获取绝对路径所包含的路径数量
    		System.out.println("absolutePath里包含的路径数量:"
    			+ absolutePath.getNameCount());
    		System.out.println(absolutePath.getName(3));
    		// 以多个String来构建Path对象
    		Path path2 = Paths.get("g:" , "publish" , "codes");
    		System.out.println(path2);
    	}
    }

    Files使用

  • public class FilesTest
    {
    	public static void main(String[] args)
    		throws Exception
    	{
    		// 复制文件
    		Files.copy(Paths.get("FilesTest.java")
    			, new FileOutputStream("a.txt"));
    		// 判断FilesTest.java文件是否为隐藏文件
    		System.out.println("FilesTest.java是否为隐藏文件:"
    			+ Files.isHidden(Paths.get("FilesTest.java")));
    		// 一次性读取FilesTest.java文件的所有行
    		List<String> lines = Files.readAllLines(Paths
    			.get("FilesTest.java"), Charset.forName("gbk"));
    		System.out.println(lines);
    		// 判断指定文件的大小
    		System.out.println("FilesTest.java的大小为:"
    			+ Files.size(Paths.get("FilesTest.java")));
    		List<String> poem = new ArrayList<>();
    		poem.add("水晶潭底银鱼跃");
    		poem.add("清徐风中碧竿横");
    		// 直接将多个字符串内容写入指定文件中
    		Files.write(Paths.get("pome.txt") , poem
    			, Charset.forName("gbk"));
    		// 使用Java 8新增的Stream API列出当前目录下所有文件和子目录
    		Files.list(Paths.get(".")).forEach(path -> System.out.println(path));
    		// 使用Java 8新增的Stream API读取文件内容
    		Files.lines(Paths.get("FilesTest.java") , Charset.forName("gbk"))
    			.forEach(line -> System.out.println(line));
    		FileStore cStore = Files.getFileStore(Paths.get("C:"));
    		// 判断C盘的总空间,可用空间
    		System.out.println("C:共有空间:" + cStore.getTotalSpace());
    		System.out.println("C:可用空间:" + cStore.getUsableSpace());
    	}
    }
    

    FileVistor遍历文件和目录

  • Files.walkFileTree(path ,FileVistor )
  • FileVistor的四个方法
  • FileVisitResult         postVisitDirectory(): 访问目录以后触发
  • FileVisitResultpre    VisitDirectory():访问前
  • FileVisitResult         visitFile():访问文件时触发
  • FileVisitResult          visitFileFaied():失败触发
  • FileVisitResult 枚举类,描述以后的行为
  • public class FileVisitorTest
    {
    	public static void main(String[] args)
    		throws Exception
    	{
    		/ 遍历g:\publish\codes\15目录下的所有文件和子目录
    		Files.walkFileTree(Paths.get("g:", "publish" , "codes" , "15")
    			, new SimpleFileVisitor<Path>()
    		{
    			/ 访问文件时候触发该方法
    			@Override
    			public FileVisitResult visitFile(Path file
    				, BasicFileAttributes attrs) throws IOException
    			{
    				System.out.println("正在访问" + file + "文件");
    				/ 找到了FileInputStreamTest.java文件
    				if (file.endsWith("FileInputStreamTest.java"))
    				{
    					System.out.println("--已经找到目标文件--");
    					return FileVisitResult.TERMINATE;
    				}
    				return FileVisitResult.CONTINUE;
    			}
    			/ 开始访问目录时触发该方法
    			@Override
    			public FileVisitResult preVisitDirectory(Path dir
    				, BasicFileAttributes attrs) throws IOException
    			{
    				System.out.println("正在访问:" + dir + " 路径");
    				return FileVisitResult.CONTINUE;
    			}
    		});
    	}
    }
    

    访问文件属性

  • public class AttributeViewTest
    {
    	public static void main(String[] args)
    		throws Exception
    	{
    		// 获取将要操作的文件
    		Path testPath = Paths.get("AttributeViewTest.java");
    		// 获取访问基本属性的BasicFileAttributeView
    		BasicFileAttributeView basicView = Files.getFileAttributeView(
    			testPath , BasicFileAttributeView.class);
    		// 获取访问基本属性的BasicFileAttributes
    		BasicFileAttributes basicAttribs = basicView.readAttributes();
    		// 访问文件的基本属性
    		System.out.println("创建时间:" + new Date(basicAttribs
    			.creationTime().toMillis()));
    		System.out.println("最后访问时间:" + new Date(basicAttribs
    			.lastAccessTime().toMillis()));
    		System.out.println("最后修改时间:" + new Date(basicAttribs
    			.lastModifiedTime().toMillis()));
    		System.out.println("文件大小:" + basicAttribs.size());
    		// 获取访问文件属主信息的FileOwnerAttributeView
    		FileOwnerAttributeView ownerView = Files.getFileAttributeView(
    			testPath, FileOwnerAttributeView.class);
    		// 获取该文件所属的用户
    		System.out.println(ownerView.getOwner());
    		// 获取系统中guest对应的用户
    		UserPrincipal user = FileSystems.getDefault()
    			.getUserPrincipalLookupService()
    			.lookupPrincipalByName("guest");
    		// 修改用户
    		ownerView.setOwner(user);
    		// 获取访问自定义属性的FileOwnerAttributeView
    		UserDefinedFileAttributeView userView = Files.getFileAttributeView(
    			testPath, UserDefinedFileAttributeView.class);
    		List<String> attrNames = userView.list();
    		// 遍历所有的自定义属性
    		for (String name : attrNames)
    		{
    			ByteBuffer buf = ByteBuffer.allocate(userView.size(name));
    			userView.read(name, buf);
    			buf.flip();
    			String value = Charset.defaultCharset().decode(buf).toString();
    			System.out.println(name + "--->" + value) ;
    		}
    		// 添加一个自定义属性
    		userView.write("发行者", Charset.defaultCharset()
    			.encode("疯狂Java联盟"));
    		// 获取访问DOS属性的DosFileAttributeView
    		DosFileAttributeView dosView = Files.getFileAttributeView(testPath
    			, DosFileAttributeView.class);
    		// 将文件设置隐藏、只读
    		dosView.setHidden(true);
    		dosView.setReadOnly(true);
    	}
    }

     

 

  • 关于文件监听 WatchService 和文件属性Attribute百度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值