IO :Core Java 2-2

IO流:数据相对内存的流入(In)流出(Out)

字符流:以字符为最小数据单元、java中字符是Unicode编码、一个字符占两个字节。只能处理纯文本数据。

字节流:以字节为最小数据单元。

节点流:
  • File(文件读写)
  • Memory Array(CharArray、ByteArray)内存数组
  • Memory String(内存字符串)
  • Pipe(进程间通信)

每种节点流针对字符类型的和字节类型的流的流入流出都有2个类:xxInputStream、xxOutputStream、xxReader、xxWriter。
但String只有StringReader和StringWriter,因为String本身就是字符数组,因此只有字符流、没有字节流。

处理流:
  • Buffered - 缓冲流:在读入或写出时,对数据进行缓存,以减少I/O的次数
  • Filter - 过滤流:在数据进行读或写时进行过滤
  • Object - 对象流(复杂对象类型读写)、Data - (java基本数据类型读写:int、boolean等)
    以上两种因为本身有可能是字节类型,所以只能有字节流类型的处理类
  • LineNumber计数流(读入时对行计数)、PushBack预读流(通过缓存机制、进行预读)
    以上两种,因为本身就是处理读入,所有只有In流的处理类
  • Print打印流(包含方便打印的方法),打印是Out流,所以只有Out流的处理类
  • 按照一定的编码\解码标准,将字节流转为字符流。
    InputStream转Reader、OutputStream转Writer

判断使用何种流
  1. 读入到内存(In、Reader),从内存写出到其它目标(Out、Writer)
  2. 纯文本(Reader、Writer),非纯文本(InputStream、OutputStream)
  3. 源、目标设备(内存Array、硬盘File、键盘System.in&System.out)
  4. 明确是否需要其它功能:(1)提高性能,用Buffered(2)字节字符转换

例:将键盘输入的内容保存在一个文件中,输入"over"结束。
分析:

  1. 从键盘输入到内存System.in;
  2. 键盘输入内容为纯文本,但是System.in为字节流,需要转成字符流
  3. 从内存输出到文件,用FileWriter
  4. 提高性能用Buffered
java.util.Scanner

Scanner是一个工具类,仅能用来处理纯文本数据(字符为单位的数据),并且仅能处理java基本类型和String类型,不能处理其它引用类型的数据。

  • 声明:implements iterator<String>, closeable
  • 构造函数:Scanner(InputStream in) \ Scanner(File file) \ Scanner(Path path) \ Scanner(Readable readable)
  • 实现了Iterator接口,实现了 hasNext() \ next() \ remove() \ forEachRemaining(Consumer<?> action) 方法
  • 实现了 Closeable接口,实现了 close()方法
  • 自定义实现了:hasNextLine() \ nextLine()
  • 自定义实现了:hasNextInt() \ nextInt()
  • 自定义实现了:hasNextLong() \ nextLong() short \ byte \ int \ long \ double \ float \ boolean \ BigInteger \ BigDecimal

java.nio.file.Path && Files

  • Path.get(“a”, “b”, “c”…);构建一个相对路径 a/b/c…; ——工厂方法
  • Path.get(“c:”,“b”,“a”…); 构建一个绝对路径 c:/b/a…
  • Path.resolve(path1,“a.txt”);构建一个路径,path1/a.txt
  • Files.readAllBytes(Path p);返回一个byte []数组,是文件p的所有字节
  • Files.readAllLines(Path p);返回List<String>
  • Files.write(Path p, byte[] contents, OpenOption…options); 将contents写入文件p
  • Files.write(Path p, Iterable<? extends CharSequence> contents, OpenOptions options)
  • Files.newInputStream(Path p, OpenOption…options); \ newOutputStream(
  • Files.newBufferedReader(Path p,Charset charset) \ newBufferedWriter(
  • Files.createDirectory(path) ——父目录必须已经存在
  • Files.createDirectories(path)——父目录不存在,会自动创建所有父目录
  • Files.createFile(path)——创建文件
  • Files.createTmpFile(path) \ createTmpDirectory(
  • Files.copy() \ move() \ delete()
  • Files.exists() \ size() \ isReadable() \ isWriteable() \ isExecuteable() \ isDirectory()
BufferedInputStream && ByteArrayInputStream && ByteBuffer
  • ByteArrayInputStream:是节点流。用于将数据从一个字节数组中读入到内存。
  • BufferedInputStream:是处理流。缓冲流,用于为输入流提供缓冲区,装饰输入流,提高处理性能
  • ByteBuffer:是NIO中的概念。代表读入的数据要被存储到的内存区域。

java.nio

Buffer

每个buffer都具有:

  • capacity:容量,final的,不可变的。
  • position:读写位置,下一个值在此位置读出或者写入
  • limit:界限,超过此界限的读写是没有意义的
  • mark:标记,用于重复一个读入或者写出操作
    以下顺序必须成立:0<= mark <= position <= limit <= capacity

使用buffer的目的是执行“写入,然后读出”的循环。

  1. 初始position是0,limit==capacity
  2. 随着数据的不断写入,position不断增大,
  3. 当所有数据全都已经被写入到buffer、或者buffer已满后,设置limit=position,position=0,为后续应用从这个buffer读数据做准备
  4. 其后,当应用需要读取buffer中的数据时,初始position为0,limit为之前写操作完毕后设置的值
  5. 随着读操作的进行,position不断增大,直到读到limit位置,停止。这时就能理解第3部为什么要设置limit=position了,因为写操作就只写到了limit位置,对其后的位置的读取都是没有意义。
  6. 当读到limit位置后,读操作完成。这时需要设置position=0,limit=capacity,为其后对buffer的写操作做准备。

其中第3步的:设置limit=positoin, position=0,只需调用buffer.flip()方法即可实现。
其中第6步的:设置position=0,limit=capacity,只需调用buffer.clear()方法即可实现。

如果想重读缓冲区:buffer.rewind()——position=0; 或者 buffer.mark() + buffer.reset() 方法实现

创建缓冲区:ByteBuffer.allocate(int capacity) \ ByteBuffer.allocateDirect(int capacity)

capacity() \ clear() \ flip() \ position() \ limit() \ remaining() = limit()-position(); \ mark() \ reset() \ rewind()

limit(int l) - 设置buffer的limit为给定的参数值 \ position(int p) - 设置buffer的position为给定的参数值
hasRemaining() - 是否还有可以读写的数据 \ hasArray() \ isDirect() \ isReadOnly()
array() - 返回存储buffer的数组

ByteBuffer
  • allocate(int capacity) \ allocateDirect(int capacity) \ wrap(bye[] source) \ wrap(byte[] source, int offset , int length ):构建ByteBuffer,指定了容量-capacity,或者源内容(source)
  • get(): 读取positin位置的字节内容,并将position++ \ get(byte [] dest, int offset, int length):从buffer中读取,写入到dest中
  • put(byte b):将b写入到posiiton位置 \ put(byte [] source, int offset , int length):将source中的数据写入buffer
  • getXXX() \ getXXX(int index ):从buffer中读取一个java基本类型中的数值型数据(short char int long float double )
  • putXXX() \ putXXX(int index):向buffer中写入一个java基本类型中的数值型的数据(short char int long float double )
  • asXXXBuffer() :将ByteBuffer转换成其它类型的Buffer,如CharBuffer / ShortBuffer / IntBuffer / LongBuffer / FloatBuffer / DoubleBuffer
channel

一个FileChannel实例就代表了一个File或者File的一个区域。
一个ServerSocketChannel实例就代表了一个ServerSocket。
当我们操作一个Channel时,完全可以想象成我们就是在操作一个File或者Socket。

Selector && SelectableChannel

例如,NIO实现的服务器:

pulbic void  startServer(){
	

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值