Java笔记(五) 输入输出

1.输入输出流
(1)I/O流的概念
Java中没有标准的输入输出语句,在Java中将信息的输入与输出过程抽象为输入输出流,Java所有的输入和输出操作都要通过I/O包中的一些流类方法来实现。
读写数据的方法大体上是一样的:(读:1打开一个流、2.读信息、3.关闭流)(写:1.打开一个流、2.写信息、3.关闭流)
(2)预定义的I/O流类概述
常见包:java.io
输入输出流分类:(1.输入流或输出流<-从流的方向划分2.节点流或处理流<-从流的分工3.面向字符流或面向字节流<-从流的内容)
按面向字符流和面向字节流分类:Object:(面向字节的流:InputStream、OutputStream;面向字符的流:Reader、Writer)
a.面向字符的流–Reader和Writer类
针对字符数据的特点进行优化过的,字符流的源或目标通常是文本文件。
Java中的字符使用的都是16-bit的Unicode编码(将全世界所有的符号进行统一编码)。
Reader和Writer是java.io包中所有字符流的抽象基类。
Reader和Writer的子类又可分为两大类:一类用来从数据源读入数据或往目的地写入数据(称为节点流)有阴影的;另一类对数据执行某种处理(称为处理流)无阴影的。
Reader | ->BufferedReader->LineNumberReader
| ->CharArrayReader
| ->InputStreamReader->FileReader
| ->FilterReader->PushbackReader
| ->PipedReader
| ->StringReader

      Writer   | ->BufferedWriter
               | ->CharArrayWriter
               | ->OutputStreamReader->FileWriter
               | ->FilterWriter
               | ->PipedWriter
               | ->StringWriter
               | ->FilterWriter

绝大多数程序使用Reader和Writer这两个抽象类的一系列子类来读入和写出文本信息,例如:FileReader/FileWriter就是用来读/写文本文件的。
b.字节流–InputStream和OutputStream类
InputStream和OutputStream是用来处理8位字节流的抽象基类,程序使用这两个类的子类来读写8位的字节信息,这种流通常被用来读写诸如图片,声音之类的二进制数据,事实上,绝大多数数据是被存储为二进制文件的。
这些子类中有两个特殊的类ObjectInputStream和ObjectOutputStream,他们可用来读/写对象。还有两个特殊的类PipedInputStream和PipedOutputStream主要用来完成线程之间的通信。
类似于处理字符流的类,InputStream和OutputStream的子类也分为两部分,节点流(有阴影)和处理流(无阴影)。
InputStream | ->FileInputStream
| ->PipedInputStream
| ->FilterInputStream->(LineNumberInputStream、DataInputStream、BufferedInputStream、PushbackInputStream)
| ->ByteArrayInputStream
| ->SequenceInputStream
| ->StringBufferInputStream
| ->ObjectInputStream

      OutputStream        |  ->FileOutputStream
                          |  ->PipedOutputStream
                          |  ->FilterOutputStream->(DataOutputStream、BufferedOutputStream、PrintStream)
                          |  ->ByteArrayOutputStream
                          |  ->ObjectOutputStream

c.标准输入输出
Java中标准输入输出流:(标准输入:System.in;标准输出:System.out;标准错误输出:System.err)
System.in是InputStream类型的,代表标准输入流,这个流是已经打开了的,默认状态对应于键盘输入。
System.out和System.error是PrintStream类型的,代表标准输出流和标准错误信息输出流,默认状态对应于屏幕输出。
标准的输入输出设备也可以通过这个类的重导向函数进行从新指定:
(setIn(InputStream)//指定新的标准输入流;setOut(PrintStream)//指定新的标准输出流;setErr(PrintStream)//指定新的标准错误输出流)
System.in是原始的InputStream,要经过包装才能从键盘读取信息。
BufferedReader in=new BufferedReader(new (System.in)); String s=in.readLine();
InputStreamReader和BufferedReader都属于“处理流”。
d.处理流
处理流不直接与数据源或目标相连,而是与另外的流配合,对数据进行某种处理,例如:BufferedReader对另一个流产生的数据进行缓冲。
e.I/O异常
多数I/O方法在遇到错误时会抛出异常,因此调用这些方法,必须在函数头声明抛出IOException异常,或者在try块中执行I/O,然后捕获IOException异常。
I/O流类有一个共同点,一旦被创建,就会自动打开,通过调用其close方法。可以显示关闭任何一个流。如果这个流对象不再被引用,Java的垃圾回收机制也会隐式的关闭它。
2.文件读写
(1)写文本文件
FileWriter类
Writer->OutputStreamWriter->FileWriter
new FileWriter(String s); //每次创建将产生一个新的s文件
new FileWriter(String s,boolean append); //如果append是true,可以实现在已有文件内容之后续写而不是完全替代
一个Writer类可以实现内部格式到外部磁盘文件格式的转换,当一个涉及文件操作的程序结束时,都应该执行close()方法。
当写入的文本很少时,使用FileWriter类就可以了,如果需要写入的内容很多,就应当使用java.io包里的缓冲器流类BufferedWriter,这两个类都用于输出字符流,包含的方法几乎完全一样,但BufferedWriter多提供了一个newLine()方法用于换行,用”\n”换行兼容性不如newLine();
(2)读文本文件
FileReader类
Reader->InputStreamReader->FileReader
缓冲器类:BufferedReader,具有readLine()函数,可以一行一行的读取输入流中的内容。
FileReader流对象被创建后,文件就被打开了,如果不存在,则会抛出一个IOException。
检测是否到文件结尾:(1.用readLine()方法,如果不再有数据,则返回null;2.利用Reader类的read()方法返回一个int型整数,如果读到文件末尾,则返回-1)
(3)写二进制文件
OutputStream及其子类
OutputStream->FilterOutputStream->BufferedOutputStream
(4)读二进制文件
FileInputStream、DataInputStream、BufferedInputStream等
InputStream->FileInputStream
InputStream->FilterInputStream->(DataInputStream、BufferedInputStream)
EOFException是IOException的子类,只有文件结束的异常才会被捕捉到。
DataInputStream函数使用参见API文档
System.out属于PrintStream类,其write(int)方法继承自OutputStream,因此也是写出其int类型参数的底8位字节。
(5)File类
File类是IO包中唯一表示磁盘文件信息的对象,他定义了一些与平台无关的方法来操作文件。
在Java中,目录也被当作File使用,只是多了一些目录特有的功能。
File类常用的API:
构造函数:(public File(String name); public File(String pathToName,String Name); public File(File directory,String name); public File(URI rui);)
public static final String pathSeparator //获取适合本机的分隔符
boolean canRead() //如果文件可读,则返回真,否则返回假
boolean canWrite() //如果文件可写,则返回真,否则返回假
boolean exists() //如果File构造函数所制定的名称是指定路径中文件或目录,则返回真,否则返回假。
boolean creatNewFile() //如果文件不存在,则创建这个名称的空文件,并返回真,如果文件存在,则返回假
boolean isFile() //如果File构造函数参数所指定的名称是一个文件,则返回真,否则返回假。
boolean isDirectory() //如果File构造函数参数所指定的名称是一个目录,则返回真,否则返回假。
boolean isAbsolute() //如果File构造函数参数所指定的名称是一个文件或目录的绝对路径,则返回真,否则返回假。
boolean delete() //删除文件或目录,如果是目录,必须是空目录才能删除成功,删除成功返回真,否则返回假。
String getAbsolutePath() //返回一个包含文件或目录的绝对路径的字符串
String getName() //返回一个包含文件名或目录名的字符串
String getPath() //返回一个包含文件或目录路径的字符串
String getParent() //返回一个包含文件或目录的父路径的字符串,则可在其中找到文件或目录的目录。
long length() //返回文件的字节长度。如果File对象代表目录,则返回0.
long lastModified() //返回文件或目录最近一次修改的时间,该时间的表示与平台相关,返回值只用于与该方法返回的其他值进行比较。
String[] list() //返回一个代表目录中内容的字符串数组,如File对象不是目录,则返回null.
(6)处理压缩文件
java.util.zip包中提供了一些类,可以压缩格式对流进行读写,他们都继承自字节流类OutputStream和InputStream。
其中GZIPOutputStream和ZipOutputStream可分别把数据压缩成GZIP格式和Zip格式;GZIPInputStream和ZipInputStream可以分别把压缩成GZIP格式或Zip的数据解压缩恢复原状,所有类使用的压缩算法都是相同的。
为了提高压缩效率,可以将缓冲流BufferedInputStream或BufferedOutputStream包装在压缩输入输出流当中。
从InputStream类的对象读取一个字节用的是read()方法,返回的是一个int型数字,每个字节都被转化为[0,255]之间的一个整形,如果读到了文件末尾,则返回-1,向OuputStream类型的对象写一个字节用的是write(int)方法,但int是32位的,所以只写int的底8位。
压缩类的使用很简单,只需要将别的输入输出流,包装在GZIPInputStream、ZipInputStream和GZIPOutputStream、ZipOutputStream中。
需注意的是,GZIPOutputStream和GZIPInputStream的构造函数都只能接受字节流类的对象,本身也是字节流。Reader类的InputStreamReader可以将读入的字节流转化为字符流。可以说,InputStreamReader和OutputStreamWriter构建了字节流与字符流之间的桥梁,InputStreamReader能够将InputStream转换为Reader,OutputStreamWriter则能将Writer转换为OutputStream。ZipOutputStream和ZipInputStream类的使用方法还有一些不同。Zip文件是一个压缩文件,里面含有多个文件,所以有多个入口,在压缩文件中,每一个文件用一个ZipEntity对象来表示,该对象的getName()方法返回文件的最初名称。
(7)对象序列化
Java是一种面向对象的语言,因而对象的永久存储是非常重要的。
java.io包中提供了专门用于对象信息存储和读取的输入输出流类ObjectInputStream和ObjectOutputStream,但这两个类不会保存和读取对象中的transient和static类型的变量,这使得我们可以选择性地存储必要的信息,所有的对象并不是都自动能被序列化的,要是实现对象的序列化,这个对象所属的类必须实现Serializable接口。
关键字:transient
transient说明一个属性是临时的,不会被序列化。
transient adj.短暂的
(8)随机文件读写
java.io包提供了RandomAccessFile类用于随机文件的创建和访问。使用这个类,可以跳转到文件的任意位置读写数据。
随机文件的应用程序必须指定文件的格式,最简单的是要求文件中的所有记录均保持相同的固定长度。
RandomAccessFile类有个位置指示器,指向当前读写处的位置,刚打开文件时,文件指示器指向文件的开头处。可以用seek,skipBytes等方法移动文件指示器到新的位置,随后的读写操作将从新的位置开始。RandomAccessFile在等长记录格式文件的随机读取时有很大的优势,但该类操作仅限于操作文件,不能访问其他I/O设备,如网络,内存映像等。
RandomAccessFile类的常用API:
public RandomAccessFile(File f,String mode); //指定关联的文件及处理方法
public void setLength(long newLength); //设置文件长度,即字节数
public long length(); //返回文件的长度,即字节数。
public void seek(long pos); //移动文件位置指示器,pos指定文件开头的偏离字节数。可以超过文件总字节数,但只有写操作后,才能扩展文件大小。
public int skipBytes(int n); //跳过n个字节,返回数为实际跳过的字节数。
public int read(); //从文件读取一字节,字节的高24位为0。如遇到结尾,则返回-1.
public final double readDouble(); //读取8个字节。
public final void writeChar(int v); //写入一个字符,两个字节,高位先写入。
public final void writeInt(int v); //写入四个字节的int型数字。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值