Java流与文件

流与文件

  • 在JavaAPI中,可以从其中读入一个字节序列的对象称为输入流,而可以向其中写入一个字节序列的对象称做输出流
  • 这些字节序列的来源地和目的地可以是文件,而且通常都是文件,但是也可以是网络连接,甚至是内存块
  • 抽象类inputStream和OutputStream构成了有层次结构的输入/输出(I/O)类的基础
  • 面向字节的流不便于处理以Unicode形式存储的信息,所以从抽象类reader和writer中继承出来的专门用于处理Unicode字符的类构成了一个单独的层次结构
  • 这些拥有的读入和写出操作都是基于两字节的Unicode码元的,而不是基于单字节的字符
读写字节
  • inputStream类有一个抽象方法:abstract int read();这个方法将读入一个字节,并返回读入的字节,或者在遇到输入源结尾时返回-1.
  • 在设计具体输入流类时,必须覆盖这个方法以提供适用的功能,在FileInputStream类中,这个方法将从某个文件中读入一个字节,而system.in却是从键盘读入信息的
  • InputStream类还有若干个非抽象方法,它们可以读入一个字节数组,或者跳过大量的字节。
  • read和write方法在执行时都将阻塞,直至字节确实被读入或写出。
  • 这就意味着如果流不能被立即访问,那么当前的线程将被阻塞。
  • 这使得在这个方法等待指定的流变为可用的这段时间里,其他的线程就有机会去执行有用的工作。
  • 当你完成对流的读写时,应该通过调用close方法来关闭它,这个方法会释放掉十分有限的操作系统资源。
  • 如果一个应用程序打开了过多的流而没有关闭它,那么系统资源将被耗尽。
  • 关闭一个输出流的同时也就是在清空用于该输出流的缓冲区;所有被临时置于缓冲区中,以便用更大的包的形式传递的字符在关闭输出流时都将被送出。如果不关闭文件,那么写出字节的最后一个包可能将永远也得不到传递;我们可以用flush方法来人为地清空这些输出。
  • 即使某个流类提供了使用原生的read和write功能来工作的某些具体的方法,应用系统的程序员还是很少使用它们,因为大家感兴趣的数据可能包含数字、字符串和对象,而不是原生字节
  • Java提供了众多从基本的inputStream和outputStream类导出的类,这些类使我们可以处理那些以常用格式表示的数据,而不只是在字节级别上表示的数据。
完整的流家族
  • Java拥有一个包含各种流类型的流家族,其数量超过60个
  • 让我们把流类家族中的成员按照它们的使用方法来进行划分,这样就形成了字节和字符的两个单独的层次结构
  • InputStream和outPutStream类可以读写单个的字节或字节数组,这些类构成了层次结构的基础。要想读写字符串和数字,就需要功能更强大的子类。
  • DataInputStream和DataOutputStream可以二进制格式读写所有基本Java类型。
  • 最后,还包含了多个很有用的流,例如,ZipInputStream和ZipOutputStream可以以常见的Zip压缩格式读写文件
  • 对于Unicode,可以使用抽象类Reader和Writer的子类。Reader和Writer类的基本方法与InputStream和OutputStream中的方法类似。
  • ZipInputStream和ZipOutputStream可以以常见的Zip压缩格式读写文件
  • Java SE 5.0引入了4个附加接口:Closeable,Flushable,Readable和Appendable
  • InputStream,outputStream,Reader和Writer都实现了Closeable接口,而OutputStream和Writer还实现了Flushable接口
  • Readable接口只有一个方法:int read(CharBuffer cb)
  • CharBuffer类拥有按顺序和随机地进行读写访问的方法,它表示一个内存中的缓冲区或者一个内存映像的文件。
  • Appendable接口有两个用于添加单个字符和字符序列的方法:Appendable append(char c) Appendable append(CharSequence s)
  • CharSequence接口描述了一个char值序列的基本属性,它是用String,CharBuffer,StringBuilder和StringBuffer来实现的。
  • 在流类家族中,只有Writer实现了Appendable。
  • java.io.Closeable5.0; void close(),关闭这个Closeable,可能抛出IOException。
  • java.io.Flushable5.0; void flush(),清空这个Flushable
  • java.lang.Readable5.0; int read(CharBuffer cb),尝试着读入cb可以持有的数量的char值。返回读入的char值的数量,或者在从这个Readable中无法再获得更多的值时返回-1
  • java.lang.Appendable5.0;Appendable append(char c),Appendable append(CharSequence cs)向这个Appendable中追加给定的码元或者给定的序列中的所有码元,返回this。
组合流过滤器
  • FileInputStream和FileOutputStream可以提供附着在一个磁盘文件上的输入流和输出流,而你只需向其构造器提供文件名或文件的完整路径名。
  • 与抽象类InputStream和OutputStream一样,这些类支持在字节级别上的读写。
  • 为了从文件中读入数字,首先需要创建一个FileInputStream,然后将其传递给DataInputStream的构造器
  • 当多个流连接在一起时,需要跟踪各个中介流
  • 可以通过嵌套过滤器来添加多重功能。

文本输入与输出

  • 在存储文本字符串时,需要考虑字符编码方式问题。
  • OutputStreamWriter类将使用选定的字符编码方式,把Unicode字符流转换为字节流。
  • InputStreamReader类将包含字节的输入流转换为可以产生Unicode字符的读入器
如何写出文本输出
  • 以二进制格式写出数据,需要使用DataOutputStream
  • 以文本格式写出数据,需要使用PrintWriter
以文本格式存储对象
  • 对nextInt的调用读入的是数组长度,而不是坠在行尾的换行字符。
字符集
  • 可以通过调用静态的forName方法来获得一个Charset,只需向这个方法传递一个官方名字或者是它的某个别名:Charset cset = Charset.forName(“ISO-8859-1”);
  • 字符集的名字是大小写不敏感的
  • 一旦有了字符集,就可以使用它将Unicode字符串转换成编码而成的字节序列,下面是如何编码Unicode字符串的代码:
    在这里插入图片描述
  • 要想了解字节序列,需要有字节缓冲区。使用byteBuffer数组的静态方法wrap可以将字节数组转为字节缓冲区
  • java.nio.charset.Charset 1.4
- static SortedMap availableCharsets()   获取所有字符集,返回映射表,键是字符集的名字,值是字符集
- static Charset forNmae(String name)  获取给定名字的字符集
- Set aliases()  返回这个字符集的别名集
- ByteBuffer encode(String str)  将给定的字符串编码为字节序列
- CharBuffer decode(ByteBuffer buffer)   解码给定的字节序列,无法识别的输入将被转换成Unicode的“替代字符”('\uFFFD')
  • java.nio.ByteBuffer 1.4
- byte[] array()  返回这个缓冲区所管理的字节数组
- static ByteBuffer wrap(byte[] bytes)
- static ByteBuffer wrap(byte[] bytes,int offset, int length) 返回挂你给定的字节数组或给定字节数组的某个范围的字节缓冲区
  • java.nio.CharBuffet
- char[] array()  返回这个缓冲区所管理的码元数组。
- char charAt(int index)  返回给定索引处的码元
- String toString() 返回由这个缓冲区所管理的码元构成的字符串

读写二进制数据

在这里插入图片描述
在这里插入图片描述

  • writeInt总是将一个整数写出为4字节的二进制数量值,而不管它有多少位,writeDouble总是将一个double值写出为8字节的二进制数量值。
  • 这样的产生的结果并非人可阅读,对于给定类型的每个值,所需的空间都是相同的,而且将其读回也比解析文本要更快
  • Java所有值都按照高位在前的模式写出,这使得Java数据文件可以独立于平台
  • DataInputStream类实现了DataInput接口,要想从文件中读入二进制数据,需要将DataInputStream与某个字节源相组合
  • 随机访问文件
    • RandomAccessFile类可以在文件中的任何位置查找或写入数据。磁盘文件都是随机访问的,但是从网络而来的数据流却不是。
    • 当你将已有文件打开成RandomAccessFile时,这个文件并不会被删除。
    • RandomAccessFile类同时实现了DataInput和DataOutput接口。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值