InputStream和OutputStream是字节输入输出流的顶级父类,用于操作字节流。InputStream是输入流,负责读。OutputStream是输出流,负责写。Reader和Writer是字符输入输出流的顶级父类,用于操作字符流。Reader是负责读。Writer是负责写。、下面逐个讲解一下各个的方法:
- 用普通读取方法读取,每次只读取一个字节
FileReader fr = new FileReader("123.txt"); // 明确被读取的文件 使其相关联
//如果len是-1,则证明读到了结尾
//如果len是一个数字,这个数字代表的是读取到的字符的ASCII码值
// System.out.println(buf.toString());打印出来的是哈希值
int len=0;
while ((len=fr.read())!=-1) {
System.out.print((char)len);
}
//fr.read();// 的返回结果是读取到到字符
fr.close();
- 在上一步的基础上,利用缓冲区进行读取,每次读取一个定义的数组的长度
/*
* 需求:演示Reader中的read(char[]);读取方法。
*
* 这种读取的效率要比第一种高的多。
*
*/
FileReader fr = new FileReader("123.txt");
//创建一个字符数组。
char[] buf = new char[2];
int len = 0;
//如果读取到数字,读取的值大小时读取到的字符数
while((len=fr.read(buf))!=-1){
System.out.print(new String(buf,0,len));
}
fr.close();
- 同普通方法写入一个文件:
FileWriter writer = new FileWriter("123.txt",true);
//有了则覆盖,没有则创建,后面true意思是可以续写
writer.write("123"+LINE_SPARATOR+"www");
writer.flush();//缓冲区的东西刷新到目的地中
writer.close();//利用到了系统的资源,所以要释放
System.out.println("执行完毕");
- 用缓冲区高效写入一个文件:
//创建一个流对象
FileWriter writer = new FileWriter("buffer.txt");
//为了提高效率,创建了一个缓冲区对象,并和要和提高效率的流关联。
BufferedWriter bufwr = new BufferedWriter(writer);
//接下来用缓冲区方法进行操作 操作数组中的数据 数据都跑在了缓冲区当中
bufwr.write("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
bufwr.newLine();
bufwr.write("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
bufwr.close();//底层是关闭的流对象 本来这句只是关闭一个数组
System.out.println("执行完毕");
- 有以上例子我们做出复制一个文件的例子
FileReader reader = null;
FileWriter writer = null;
try {
reader = new FileReader("123.txt");// 读取数据
writer = new FileWriter("copy123.txt");
char ch[] = new char[1024];
int len = 0;// 返回值是读取到的字符数
while ((len = reader.read(ch)) != -1) {
writer.write(ch, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("出现异常");
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
// 相关代码处理 比如说记录到日志文件当中
throw new RuntimeException("输入流关闭失败");
}
}
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
throw new RuntimeException("输出流关闭失败");
}
}
}
- 上面那个是自己写了一个数组,作为缓冲区,当然Java设计者也不会那么笨,所以本身提供了缓冲区进行读- 写操作:
下面我们看一个例子(底层就是装饰设计模式):
FileReader reader=null;
FileWriter writer = null;
BufferedReader fr=null;
BufferedWriter fw=null;
try {
reader = new FileReader("buffer.txt");
writer = new FileWriter("copybuffer.txt");
fr = new BufferedReader(reader);
fw = new BufferedWriter(writer);
String line=null;
while ((line=fr.readLine())!=null) {
fw.write(line);
fw.newLine();//读一行写一行 所以要换行
}
} catch (Exception e) {
}finally{
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("执行完毕");
InputStream和OutputStream是字节输入输出流的顶级父类,用于操作字节流。InputStream是输入流,负责读。OutputStream是输出流,负责写。它本身为一个抽象类,必须依靠其子类实现各种功能,此抽象类是表示字节输入流的所有类的超类。 继承自InputStream 的流都是 向程序中 输入数据的,且数据单位为字节(8bit)
用输入流缓冲区高效读取数据:
FileInputStream fis = new FileInputStream("bytestream.txt");
System.out.println(fis.available());
byte[] buf = new byte[2048];//一个汉字是两个字节 如果没有用数组读 汉字没法读出来 因为一次只读了y
//一个字节 半个汉字 输出的是?
int len = 0;
while ((len=fis.read(buf))!=-1) {
System.out.println(new String(buf,0,len));
}
fis.close();
下面看一下用数组高效的赋值文件:
public class CopyMp3A {
public static void main(String[] args) throws IOException {
FileInputStream reader = new FileInputStream("1.mp3");
FileOutputStream writer = new FileOutputStream("2.mp3");
byte b[]= new byte[reader.available()];
reader.read(b);
//在这里来一个形象的比喻,reader读取文件,这个文件的大小已经知道了 用一个数组b圈了起来 这是这个文件对外就变成了一个b
//然后调用read方法读取这个文件把他给放到一个流中 这个时候在调用write方法进入这个六中拿到这个b
writer.write(b);
reader.close();
writer.close();
System.out.println("执行完毕");
}