IO流可以分为两类:输入流和输出流。所有的输入和输出都可以分为字符(输入、输出)流、字节(输入、输出)流,处理字节用到的主要是(OutputStream、InputStream),处理字符主要是(Reader、Writer)。
对所有流的转换、封装设置的流(Filter),操作数据的对象(File)。
对磁盘文件进行操作和处理的字节流FileInputStream、FileOutputStream,及相应的字符流FileReader和FileWriter。当数据量很大的时候,这时候就需要用到缓冲区,对读写数据提供了缓冲的功能,提高了读写的效率,BufferedReader、BufferedWriter和BufferedInputStream、BuffferedOutputStream。写出的数据先在内存中缓存,使用flush方法将数据写出,一般不用调用该方法,默认就已经刷新。当然还要进行字符和字节之间的转换,相对应的也就有InputStreamReader和OutputStreamWriter。要想打印一段文字到控制台或实现控制台输出,这时有两个比较重要的方法System.in和System.out。下面我就具体说说其中的几个重要的IO流的常用方法和实例。
InputStream和OutputStream是所有字节流处理的抽象类,所以,所有的处理字节流的对象都继承自这两个基类。
1. InputStream
1.1StringBufferInputStream:把一个String对象作为InputStream
1.2FileInputStream对文件进行读取操作
FileInputStream(File file)通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
FileInputStream(String name) 该操作的文件用name指定。
Read(byte[] b)读取最多b长度的字节读入到byte数组中。
Read(byte[] b, int off, int len) off表示偏移量(从哪开始读),当然也是读取到b中,最多读取len长度个。读取文件的时候可能会报出异常,需要进行抛出或捕获。
Close() 关闭资源并释放与此流相关联的系统资源 一般写习惯了都会关闭流
1.3DataInputStream 数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。应用程序可以使用数据输出流写入稍后由数据输入流读取的数据。对于多线程访问不一定是安全的。 线程安全是可选的,它由此类方法的使用者负责。
以下是一个小的Demo:
DataInputStream dis=new DataInputStream(System.in);
String input;
while((input=dis.readLine())!=null)
{
}
1.4BufferedInputStream
其中的方法和FileInputStream中的方法相同,只不过它是创建一个缓冲流进行输入流的速度加快。
2. OutputStream
2.1FileOutputStream对文件进行写入的操作
FileOutputStream(File file) 通过打开一个到实际文件的连接来创建一个 FileOutputStream,该文件通过文件系统中的 File 对象 file 指定。
FileOutputStream(String name) 该操作的文件用name指定。
write(byte[] b) 将 b长度个字节从指定 byte 数组写入此文件输出流中。
write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。
write(int b) 将指定字节写入此文件输出流。
Close() 关闭文件输出流并释放与流相关的所有的系统资源。
2.2DataOutputStream数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。
2.3BufferedOutputStream 其中的方法和FileOutputStream中的相同,flush()刷新缓冲输出流。
具体操作字节流实例:
不使用buffer缓冲流
Java代码 复制文件
import java.io.*;
public class TestFileOutputStream{
public static void main(String args[]){
int b = 0;
FileInputStream in = null;
FileOutputStream out = null;
try{
in = new FileInputStream("c:\\TestFileInputStream.java");
//如果这个时候C盘下面还没有Test.java,那么new FileOutputStream会创建一个空的Test.java文件,但不会创建目录
out = new FileOutputStream("c:\\Test.java"); while((b = in.read())!=-1){ //循环读取并记录读取个数到b中
out.write(b); //循环写入到文件中b长度个字节
}
in.close(); out.close(); }catch(FileNotFoundException e){
System.out.println("找不到指定文件");
System.exit(-1); }catch(IOException e){ System.out.println("文件复制错误");
System.exit(-1);
}
System.out.println("文件已复制"); } } 利用字节流的缓冲区进行二进制文件的复制:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo {
public static void main(String[] args ) {
String bin = “c:\\hehe.mp3”;
String copy =“d:\\haha.mp3”;
FileInputStream i = null;
FileOutputStream o = null;
BufferedInputStream bi = null; //创建缓冲输入流
BufferedOutputStream bo = null; //创建缓冲输出流
try {
bi=new BufferedInputStream(new FileInputStream(bin));
bo = new BufferedOutputStream(new FileOutputStream(copy));
byte[] buf = new byte[1024];
int temp = 0;
while((temp = bi.read(buf)) != -1) {
bo.write(buf,0,temp);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(bi != null) {
try {
i.close();//必须关闭输入流,缓冲输入流不用关闭
} catch (IOException e) {
e.printStackTrace();
}
}
if(bo != null) {
try {
o.close();//必须关闭输出流,缓冲输出流不用关闭
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3.
Reader、Writer
Reader和Writer是提供对字符流处理的类,同样也都是抽象类。是所有字符流的基类。
3.1FileReader用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。要自己指定这些值,可以先在 FileInputStream 上构造一个 InputStreamReader。
FileReader(File file) 在给定从中读取数据的 File 的情况下创建一个新 FileReader。
FileReader(String fileName) 在给定从中读取数据的文件名的情况下创建一个新 FileReader。
read()读取单个字符。
read(char[] cbuf) 将字符读入数组。
read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。Off同样是偏移量,len同样是最大长度。
Close() 关闭流并释放与之关联的系统资源。
3.2BufferedReader同理也是进行字符的缓冲操作
BufferedReader(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流
其拥有的方法也包括FileReader中的方法,但其中有个readLine()方法,可以一次读取一行,速度加快了。
3.3FileWriter用来写入字符文件的便捷类文件。是否可用或是否可以被创建取决于底层平台。特别是某些平台一次只允许一个 FileWriter(或其他文件写入对象)打开文件进行写入。
FileWriter(File file) 根据给定的 File 对象构造一个 FileWriter 对象。
FileWriter(String fileName) 根据给定的文件名构造一个 FileWriter 对象。
FileWriter(String fileName, boolean append) 根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象,如果文件中有文件,则在其后写入。
write(char[] cbuf) 写入字符数组。
write(char[] cbuf, int off, int len) 写入字符数组中指定长度的数组。
write(int c) 写入单个字符。
write(String str) 写入字符串。
write(String str, int off, int len) 写入字符数组中指定长度的字符。
Flush() 刷新缓冲
3.4BufferedWriter将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
BufferedWriter(Writer out) 创建一个使用默认大小输出缓冲区的缓冲字符输出流。
方法和FileWriter基本相同,此外还有newLine()方法进行换行。
举例进行字符流的表示:
import java.io.*;
public class TestBufferStream {
public static void main(String args[]) {
try {
//在FileWriter写出一个字符外面套层BufferedWriter管道
BufferedWriter bw=new BufferedWriter(new FileWriter("c:\\hehe.txt"));
BufferedReader br = new BufferedReader(new FileReader("c:\\haha.txt"));
String s = null;
for (int i = 0; i <= 100; i++) {
s = String.valueOf(Math.random()); //随机产生数字然后转换成字符
bw.write(s);
bw.newLine(); //换行 }
bw.flush(); //刷新缓冲区
// readLine()方法为读一行数据
while ((s = br.readLine()) != null) {
System.out.println(s);
}
bw.close(); br.close(); } catch (IOException e) {
e.printStackTrace(); System.out.println("读取文件出错");
}
}
}
4字符流和字节流之间的转换流
4.1InputStreamReader 是字节流通向字符流的桥梁,使用指定的charset读取字节并将其解码为字符。为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。
BufferedReader in= new BufferedReader(new InputStreamReader(System.in));
InputStreamReader(InputStream in, Charset cs)
InputStreamReader(InputStream in, String charsetName)
创建使用指定字符集的 InputStreamReader。
InputStreamReader isr=new InputStreamReader(is," iso-8859-1");
read(char[] cbuf, int offset, int length) 将字符读入数组中的某一部分,其方法和上边的一样
getEncoding() 返回此流使用的字符编码的名称。
4.2 OutputStreamWriter 是字符流通向字节流的桥梁,使用指定的charset将要写入流中的字符编码成字节。
其write()方法都会导致在给定字符(或字符集)上调用编码转换器。
OutputStreamWriter(OutputStream out, Charset cs)
OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter。
实例Demo:
1:import java.io.*;
2:public class CharInput
3:{ public static void main(String args[]) throws Exception
4: { String s;
5: FileInputStream is=new FileInputStream("hehe.java");
6: InputStreamReader ir=new InputStreamReader(is);
7: BufferedReader in =new BufferedReader(ir);
8: while((s=in.readLine()) !=null)
9: System.out.println("Read:" +s);
10: }
11:}
5.标准输入流:System.in是InputStream类的对象,当程序中需要从键盘读入数据时候,只需要调用System.in中的read()方法。
标准输出流:System.out它是打印输出流PrintStream类的对象,它定义了向屏幕输出不同类型数据的方法println()与 print()。
标准输入输出的重定向:改变标准输入输出的方向为其它形式如从文件中输入
① 方法:利用System类中的3个static 方法可以实现。setIn(InputStream in)、setOut(PrintStream out)、setErr(PrintStream out). System.out.println()它可以输出多种不同类型的数据(如:boolean,double,float,int,long类型的变量以及Object类的对象);当输出类型为对象时,它将自动调用对象的toString()方法,因此在对象所在的类中应该重写toString()方法以输出特定的文字。
public class MyClass
{ public String toString()
{ return "MyClass String";
}
public staic void main(String args[])
{ MyClass obj=new MyClass();
System.out.println(obj); //将输出“MyClass String”文字串
}
}
6.文件操作File
File( String path)、
File(String path, String FileName)、
File(File dir, String name) 等创建出File 对象;再利用canRead() (是否可读)、canWrite(是否可写)、 getParent(返回此抽象路径名父目录的路径名字符串)、 getPath(将此抽象路径名转换为一个路径名字符串)等成员函数实现对文件的各个属性的操作,以实现文件与目录的管理功能。
File类中各种方法的使用:
1:import java.io.*;
2:public class FileTest
3:{ //在执行该文件之前应该先拷贝一个文件名为File.txt的文件到当前程序所在的路径下
4: public static void main(String args[])
5: {
6:System.out.println("Path separator" +File.pathSeparator); //与系统有关的路径分隔符
7:System.out.println("Path separator char" +File.pathSeparatorChar);
8:System.out.println("separator " +File.separator); // “\”默认情况下文件与路径之间的分隔符
9:System.out.println("separator char" +File.separatorChar);
10:File f=new File("File.txt");
11:System.out.println(f);
12:System.out.println("Exist ?" + f.exists()); //文件是否存在
13:System.out.println("name " + f.getName()); //文件名字
14:System.out.println("path " + f.getPath()); //将抽象文件路径名转换成路径字符串
15:System.out.println("absolute path " + f.getAbsolutePath()); //将抽象文件的绝对路径转换成路径字符串
16:System.out.println("Parent " + f.getParent());
17:System.out.println("is a file ? " + f.isFile()); //判断是否是文件
18:System.out.println("is a Directory ? " + f.isDirectory()); //判断是否是目录
19:System.out.println("length" + f.length()); //得到文件长度
20:System.out.println("can read " + f.canRead());
21:System.out.println("can write " + f.canWrite());
22:System.out.println("last modified" + f.lastModified()); //文件最后被修改的时间
23:File newF=new File("newFile");
24:System.out.println("...Rename " + f+"....");
25:f.renameTo(newF); //将f的文件名修改为newF的文件名
26:System.out.println("name " + newF.getName()); //再次查看,名字是否修改
27:System.out.println(f+"exist ? " + f.exists());
28:System.out.println("... delete "+newF+"...");
29:newF.delete(); //删除文件
30:System.out.println(newF+ "exist ?" + newF.exists());
31: }
32:}
通过File类来实现列出一个目录下所有的*.txt文件。
1:import java.io.*;
2:public class FileFilterTest
3:{ public static void main(String args[])
4: {
5: File dir =new File("E:\\haha\\MyDemo");
6: Filter filter =new Filter("txt");
7: System.out.println("The file name:" + dir); //获得该目录下的各个文件名
8: String files[]=dir.list(filter); //列出目录下所有匹配文件并存储到String 数组中。
9: for(int i=0; i<files.length; i++) 10: {
10: File f=new File(files[i]);
11: if(f.isFile())
12: System.out.println("file " +f);
13: else
14: System.out.println("sub directory " + f);
15: }
16: }
17:}
18:class Filter implements FilenameFilter //FilenameFilter其实就是文件名过滤器,实现文件的过滤筛选
19:{ String extent;
20: Filter(String extent)
21: { this.extent=extent;
22: }
23: public boolean accept(File dir, String name)
24: { return name.endsWith("." + extent);
25: }
26:}