1、I/O流 也叫做输入输出流 是Java的网络编程的基础
流的流向:输入输出的方法是以程序来说的,数据从磁盘到内存就是输入流,从内存数据写入文件是输出流。输入流只有read方法,输出流只有write方法
Java中输入流的顶级接口InputStream,输出流是OutputStream
流的源头:基本流(节点流,低级流){有源头的}和处理流(过滤流,高级流){没有源头的,需要依赖于低级流}【判断的,可以依据在创建对象是,参数中是否包含流,有则是高级流】
流的单位:字节流 (以字节为处理单位)和 字符流(以字符为处理单位,其实内部实现还是以字节,只是封装了)
【判断:以stream结尾是字节流,以reader,或writer是字符流】
2、字节流
1)基于文件字节流:FileInputStream FIleOutputStream 文件输入输出流(是基本流)
创建文件字节流对象:FileInputStream fis = new FileInoutStream(File file);
读取:与上一篇的File的RandomAccessFIle类相似,通过read()读取,也是读取一个字节。对于传入的文件对象不存在的话,FileInputStream内部实现自动创建该文件
使用流结束后需要关闭流。
FileOutputStream与RandomAccessFile类的写方法类似。write方法的三个重载方法,write(int d),write(byte[] d),write(byte[] d,int offset,int length).还有其他的构造方法FileInputStream(File file,Boolean append);后一个参数是对文件操作是追加还是覆盖,true为追加,false为覆盖.
String 转化成 byte类型的字节数组 str.getBytes("UTF-8");返回是一个字节数组,需要捕获异常
2)基于数据字节流:DataInputStream DataOutputStream
创建一个对象:DataOutputStream dos= new DataOutputStream(out); 其中里面的参数是一个高级或一个低级流,而不是一个文件对象。如果是高级流的话,其中必定是依赖于低级流的。
例子,将一个字符串保存到一个文件中:
String info="hello world";
DataOutStream dos = new DataOutputStream(new FIleOutputStream("1.txt"));
dos.writeUTF(info);
dos.fliush(); //用于将剩下在缓冲区里面的剩下字节写出
dos.close(); //关闭高级流,不必关闭低级流。在高级流里面的关闭流中方法中有关闭低级流。注意的是,在哪创建的流在哪里关闭。如果是是通过方法参数传进来的高级流,或者低级流,不应该在方法中的关闭,而是要在调用该方法的对象中,也就是在创建该流的代码块中结束是关闭。还有,如果高级流是局部变量的话,也可以不必关闭,这样的话,就是交给jc(Java虚拟机)处理。该流的读写方法的使用于randomAccessFile的读写方法类似
3)缓冲区字节流 :BufferedInputStream BufferedOutputStream
使用的方式与前面的几个流使用类似。一个方法,进行文件复制
/***
* 使用缓冲流进行文件拷贝
* @param src
* @param des
* @throws IOException
*/
public static void copyFile2(File src,File des) throws IOException {
if(src==null){
throw new IllegalArgumentException("源文件为空");
}
if (!src.exists()) {
throw new IllegalAccessError("源文件不存在");
}
/**
* 创建缓冲流
* 高级流可以使用高级流,但是最终必须处理低级流
*
* 虽然代码是一个字节,看起来,但是内部处理不是一个字节一个字节
*/
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
// FileInputStream fis = new FileInputStream(src);
try {
bis = new BufferedInputStream(new FileInputStream(src));
bos = new BufferedOutputStream(new FileOutputStream(des));
int data =-1;
while((data=bis.read())!=-1){
bos.write(data);
}
/**
* 在所有的具有缓冲区的输出流,使用后,最好最后添加flush()方法
* 是一个编程的好习惯
*
* flush的作用是将缓冲区未写入的数据一次性写出去
*
* 复制文件在读写不正常一般出在 没有flush()
* 只要在左右一次,在close之前flush一次就可以了
*/
bos.flush();
} catch (IOException e) {
throw e;
}finally{
/**
* 通常情况下,我们只需要关闭最外层的流
* 在高级流里面的close有关闭
* 或许第三方的流肯呢个需要自己一层一层的流
* 只需要关闭最外层就好了
*/
if(bis!=null){
bis.close();
}
if (bos!=null) {
bos.close();
}
}
}
通过缓冲区的作用,是文件读写更快。在电脑上磁盘的读写是很慢(相对于内存,cpu)。如果是一个字节一个字节处理,每次只处理一个字节,而花很多时间在磁盘上移动和查找,使用缓冲区的话,先把需要读写的数据存在开辟处理的一块内存,等这这块空间存满数据的话,在在进行读取,就可以减少在磁盘移动的次数,提高读写的效率
3、字符流
以字符为单位处理数据,每一次处理以Unicode编码的字符
一、字符输入输出流
InputStreamReader:字符输入流
OutputStreamReader:字符输出流
是高级流,创建字符数入流对象
InputStreamReader reader = new InoutStreamReader(new FileInoutStream("writer.txt"),"UTF-8");//以utf-8编码处理字符,否则按系统默认的编码
遍历字符输入流
int c=-1;
while((c=reader.read())!=-1){
System.out.print((char)c);
}
使用结束后关闭流
reader.close();
-------------------
向文件中写入字符
1、创建文件输出流(字节输出流)
2、创建字符输出流(高级流)
3、写入字符
4、关闭流
FileOutputStream fos = new FileOutputStream("writer.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
osw.writer("info");
writer.flush();//清空缓冲区的字符
其中需要捕获异常
二、缓冲字符输入输出流
高级流
BufferedReader、BufferedWriter
创建和使用几乎一样,只是在遍历的时候,判断条件为 (str=reader.readLine())!=null
缓冲字符输入流:读取是使用readLine()方法一行一行读写数据
缓冲字符输出流:通过writer()方法写入,需要换行的话使用方法newLine()
三、文件字符输入输出流
FileWriter、FileReader
低级流
使用一般封装到高级流
其他博客写的更好
http://blog.csdn.net/hguisu/article/details/7418161