IO流是用来处理设备之间的数据传输的,Java对数据的操作都是使用流的方式处理的,而且Java将处理流的操作封装成IO流对象了。
一、IO流的分类
流按照操作的数据分为:字节流、字符流
流按照流的方向分为:输入流、输出流
二、字节流:
inputString------此抽象类是表示字节输入流的所有类的超类。
inputStream提供的方法
inputStream是输入流,是应用程序读取数据的方式,而read()方法就是InputStream读取数据的方式
从API中可以看到,read()方法一共有三种
(1)int b=in.read();
从输入流中读取数据的下一个字节,返回0到255范围内的int字节值,如果读到流的末尾就返回-1
public static void main(String[] args) throws IOException { InputStream in=new FileInputStream("E:\learnJava\hello.txt"); int by=0; while((by=in.read())!=-1){ //判断是否读到流的末尾 System.out.println(by); } in.close(); //使用完,记得关闭 }
(2)public int read(byte[] buf)
从输入流中读取一定数量的字节,并将其存储在缓冲区数组 buf中,将读取的第一个字节存储在元素 buf[0]
中,下一个存储在 buf[1]
中,依次类推。读取的字节数最多等于 b
的长度。返回的是实际读取的字节个数,如果读到流的末尾依旧返回-1;
public static void main(String[] args) throws IOException { InputStream in=new FileInputStream("E:\learnJava\hello.txt"); //创建流对象,如果文件不存在抛出FileNotFoundException /*int by=0;*/ byte [] buf=new byte[1024]; int len=0; //记录读取的字节个数 while((len=in.read(buf))!=-1){ //判断是否读到流的末尾 System.out.println(new String(buf,0,len)); } in.close(); //使用完,记得关闭 }
(3)public int read(byte[] buf, int start, int len)
将输入流中长度不超过len的数据字节读入数组,从数组的start位置开始存储,也就是说将读取的第一个字节存储在元素 b[start]
中,下一个存储在 b[start+1]
中,依次类推。读取的字节数最多等于 len
。返回值仍然是读取的字节个数,如果读到流的末尾则返回-1.
public static void main(String[] args) throws IOException { InputStream in=new FileInputStream("E:\learnJava\hello.txt"); //创建流对象,如果文件不存在抛出FileNotFoundException /*int by=0;*/ byte [] buf=new byte[1024]; int len=0; //记录读取的字节个数 while((len=in.read(buf,0,5))!=-1){ //判断是否读到流的末尾 System.out.println(new String(buf,0,len)); } in.close(); //使用完,记得关闭 }
OuputStream-------此抽象类是表示输出字节流的所有类的超类
OutputStream提供的方法
outputstream是输出流,提供了应用程序写出数据的方式,提供了三种write()方法
(1)public abstract void write(int b)
将指定的字节写入次输出流中,即将参数b的低八位写入到输出流,b的高24位将被忽略
OutputStream os=new FileOutputStream("E:\learnJava\hello.txt"); int b=100; os.write(b); os.close();
(2)public void write(byte[] b)
将b.length个字节从指定的byte数组写入此输入流,即将数组b中的所有字节一次写入输出流中。
public static void main(String[] args) throws IOException { InputStream in=new FileInputStream("E:\learnJava\1.txt"); OutputStream os=new FileOutputStream("E:\learnJava\hello.txt"); int b=100; byte [] buf=new byte[in.available()]; int len=0; while((len=in.read(buf))!=-1){ //将输入流保存到byte数组中 os.write(buf); //将byte数组中的字节写入到输出流 } in.close(); os.close(); }
其实上面的例子也实现了文件的复制功能
(3)public void write(byte[] b, int off, int len)
将制定byte数组中从第off个字节开始,len个字节写入此输出流,元素 b[off]
是此操作写入的第一个字节,b[off+len-1]
是此操作写入的最后一个字节。
public static void main(String[] args) throws IOException { InputStream in=new FileInputStream("E:\learnJava\1.txt"); OutputStream os=new FileOutputStream("E:\learnJava\hello.txt"); int b=100; byte [] buf=new byte[in.available()]; int len=0; while((len=in.read(buf,0,5))!=-1){ //将输入流保存到byte数组中 os.write(buf,0,5); //将byte数组中的字节写入到输出流 } in.close(); os.close(); }
这种方法和上一种方法一样,只是限制了读取的字节个数
(4)public void flush() 方法
刷新此输出流并强制写出所有缓冲的输出字节。也就是输出流字节传给操作系统,具体实现写入磁盘的操作有操作系统实现。
(5)public void close()
关闭此输出流并释放与此流有关的所有系统资源
inputSteam和OutputStream的子类
(1)FileInputStream和FileOutputStream
FileInputStream
从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。 FileInputStream
用于读取诸如图像数据之类的原始字节流。
FileOutputStream文件输出流是用于将数据写入 File
或 FileDescriptor
的输出流。文件是否可用或能否可以被创建取决于基础平台。FileOutputStream
用于写入诸如图像数据之类的原始字节的流。
其实上面基本都是以FileinputStream和FileOutStream为例,此处在贴一个复制图片的例子,实现方法都是一样的。
public static void main(String[] args){ FileInputStream fin=null; FileOutputStream fos=null; byte []buf=new byte[1024]; int len=0; try { fin=new FileInputStream("E:\learnJava\io流.jpg"); fos=new FileOutputStream("E:\learnJava\temp.jpg"); while((len=fin.read(buf))!=-1){ fos.write(buf); } } catch (IOException e) { e.printStackTrace(); }finally { try { fin.close(); fos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
(2)BufferedInputStream和BufferedOutputStream
FileInputStream和FileOutputStream是不带缓冲区的,每次读取写入时都需要我们自己写一个byte数组充当缓冲区,而BufferedInputStream和BufferedOutputStream是实现缓冲的输入输出流
BufferedInputStream
在创建 BufferedInputStream
时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。
BufferedOutputStream该类实现缓冲的输出流。
public static void main(String[] args){ FileInputStream fin=null; FileOutputStream fos=null; try { fin = new FileInputStream("E:\learnJava\风吹麦浪.mp3"); fos=new FileOutputStream("E:\learnJava\风吹麦浪_副本.mp3"); } catch (FileNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } BufferedInputStream bin=new BufferedInputStream(fin); BufferedOutputStream bos=new BufferedOutputStream(fos); int len=0; try { while((len=bin.read())!=-1){ bos.write(len); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { bin.close(); bos.close(); fin.close(); fos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
(3)DataInputStream和DataOutputStream
DataInputStream数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用数据输出流写入稍后由数据输入流读取的数据。
DataOutputStream数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。
public static void main(String[] args) throws IOException{//规避一下IO异常 //输出 DataOutputStream dos=new DataOutputStream(new FileOutputStream("E:\learnJava\dataOs.txt")); dos.writeInt(100); dos.writeLong(10l); dos.writeInt(-100); dos.writeChar('A'); dos.writeUTF("中国");//采用UTF-8编码 dos.writeChars("中国");//采用utf-16be编码 //读取 DataInputStream din=new DataInputStream(new FileInputStream("E:\learnJava\dataOs.txt")); System.out.println(din.readInt()); //读取存入的第一个int 100 System.out.println(din.readLong());//读取long数据 System.out.println(din.readInt()); System.out.println(din.readChar()); //读取char System.out.println(din.readUTF()); //读取UTF }
三、字符流
字符流操作的是文本文件,是文本(char)序列按照某种编码方案(unt-8,utf-16be,gbk)序列化而成的文件。
Reader-------用于读取字符流的抽象类
Reader提供 的方法
(1)public int read() -----读取单个字符
返回值是作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1
public static void main(String[] args) throws IOException{//规避一下IO异常 Reader reader=new FileReader("E:\learnJava\HelloReader.txt");//保证文件存在,否则抛出FileNotFoundException int ch=0; while((ch=reader.read())!=-1){ System.out.println((char)ch); } reader.close(); }
(2)public int read(char[] cbuf) ----将字符读入数组
返回值为读取的字符数,如果已到达流的末尾,则返回 -1 ;
public static void main(String[] args) throws IOException{//规避一下IO异常 Reader reader=new FileReader("E:\learnJava\HelloReader.txt");//保证文件存在,否则抛出FileNotFoundException char [] buf=new char[1024]; int len=0; while((len=reader.read(buf))!=-1){ System.out.println(new String(buf, 0, len)); } reader.close(); }
(3)public abstract int read(char[] cbuf, int off, int len) ----将字符读入数组的某一部分
Writer------写入字符流的抽象类
writer提供的方法
public static void main(String[] args) throws IOException{//规避一下IO异常 Writer writer=new FileWriter("E:\learnJava\HelloWriter.txt"); writer.write(100); //写入一个字符 writer.write("你好,Java");//写入一个字符串 char [] buf=new char[]{'A','B','中','国'}; writer.write(buf, 0, buf.length); //写入一个字符数组 String str=new String("使用Writer"); writer.write(str, 2, 6); writer.close(); }
reader和writer的子类
(1)InputStreamReader和OutputStreamWriter------实现字符流和字节流的转换
InputStreamReader 是字节流通向字符流的桥梁:每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。
public static void main(String[] args) throws IOException{//规避一下IO异常 InputStreamReader isr=new InputStreamReader(new FileInputStream("E:\learnJava\绕口令.txt"),"gbk");//指出文件的编码方式 char [] buf=new char[1024]; int len=0; while((len=isr.read(buf, 0, buf.length))!=-1){ System.out.println(new String(buf,0,len)); } isr.close(); }
其他方法:
OutputStreamWriter 是字符流通向字节流的桥梁,每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。注意,传递给 write() 方法的字符没有缓冲。
实例:文件的复制
public static void main(String[] args) throws IOException{//规避一下IO异常 InputStreamReader isr=new InputStreamReader(new FileInputStream("E:\learnJava\绕口令.txt"),"gbk");//指出文件的编码方式 /*创建一个FileWriter对象,该对象一被初始化,就必须要明确被操作的文件. 而且该文件会被创建到指定目录下,如果该目录下已有同名的文件,将被覆盖。 其实该步就是明确数据要存放的目的地*/ OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("E:\learnJava\绕口令_副本.txt"), "gbk"); char [] buf=new char[1024]; int len=0; while((len=isr.read(buf, 0, buf.length))!=-1){ osw.write(buf, 0, len); // 写入字符数组的某一部分。 } isr.close(); osw.close(); }
其他方法
(2)FileReader和FileWriter------直接操作文件
public static void main(String[] args) throws IOException{//规避一下IO异常 FileReader fReader=new FileReader("E:\learnJava\笑话大全.txt");//直接写文件路径,或者文件对象 FileWriter fWriter=new FileWriter("E:\learnJava\笑话大全_副本.txt");//输出到文件,没有则创建新的,有则覆盖,没有编码方式(不同编码方式会有乱码) int len=0; char [] buf=new char[1024]; while((len=fReader.read(buf,0,buf.length))!=-1){ fWriter.write(buf,0,len); fWriter.flush(); } fReader.close(); fWriter.close(); }
(3)BufferedReader和BufferedWriter-----字符流的过滤器
BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
方法public String readLine() 实现读取一个文本行。通过下列字符之一即可认为某行已终止:换行 (' ')、回车 (' ') 或回车后直接跟着换行。
BufferedWriter将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
public static void main(String[] args) throws IOException{//规避一下IO异常 //文件的读操作 //使用BufferedReader提高读的效率 BufferedReader bReader=new BufferedReader(new InputStreamReader(new FileInputStream("E:\learnJava\笑话大全.txt"),"gbk")); //文件输出 BufferedWriter bWriter=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:\learnJava\笑话大全_副本2.txt"),"gbk")); String line; while((line=bReader.readLine())!=null){ /*System.out.println(line); //一次读一行,line并没有实现换行*/ bWriter.write(line); bWriter.newLine();//实现换行 bWriter.flush(); } bReader.close(); bWriter.close(); }
其中BufferedWriter可以使用PrintWrite代替,会更方便
public static void main(String[] args) throws IOException{//规避一下IO异常 //文件的读操作 //使用BufferedReader提高读的效率 BufferedReader bReader=new BufferedReader(new InputStreamReader(new FileInputStream("E:\learnJava\笑话大全.txt"),"gbk")); //文件输出 /* BufferedWriter bWriter=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:\learnJava\笑话大全_副本2.txt"),"gbk"));*/ PrintWriter pWriter=new PrintWriter("E:\learnJava\笑话大全_副本3.txt"); String line; while((line=bReader.readLine())!=null){ /*System.out.println(line); //一次读一行,line并没有实现换行*/ /* bWriter.write(line); bWriter.newLine();//实现换行 bWriter.flush();*/ pWriter.println(line); //println自带换行 pWriter.flush(); } bReader.close(); /* bWriter.close();*/ }