3、字节流
InputStream和OutputStream是字节流的两个顶级类,属于抽象类
,不能直接使用,一般使用的都是其子类。流使用完必须关闭,类中提供close方法用于关闭数据流。
2.1、文件字节流
-
FileInputStream:字节输入流
FileInputStream in = new FileInputStream(file);
-
FileOutputStream:字节输出流
FileOutputStream out = new FileOutputStream(file);
适合读取所有类型的文件(文件、图片、视频等)。
包:java.io.FileInputStream和java.io.FileOutputStream;
public class Io {
public static void main(String[] args) {
//创建文件对象
File file1 = new File("d:/**/a.jpg"); //源数据
File file2 = new File("d:/**/copya.jpg"); //目的数据,file("",true)为追加,不加为false,默认覆盖
//创建输入和输出流
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream(file1);
out = new FileOutputStream(file2);
//使用流对文件进行读写
while(true){
int a = in.read(); //读取一个字节,a的在0~255之间
if(a == -1) break; //如果a=-1则表示数据读完了。循环结束
out.write(a); //将读取的字节写到另一个文件内
}
//优化,改善读取速度,手动增加一个数组的缓冲区
/*
//本地文件时1024可用file.available代替,直接获得流的大小一次性读取,图片过大时不适用
byte[] b = new byte[1024]; //定义byte数组接收读取的字节
while (true){
int len = is.read(b); //一次读取一个字节,循环读取,将数据放到数组b中
if(a == -1) break; //a=-1则表示没有读取到数据
os.write(b,0,len); //将数组b的数据写入,从0到len
}
*/
} catch (Exception e) {
e.printStackTrace();
}finally {
//关闭流
if(in != null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(out != null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
在JDK7的版本中提供了一种新的异常处理,可自动关闭流
public class Io {
public static void main(String[] args){
//创建文件对象
File file1 = new File("d:/mydata/a.jpg");
File file2 = new File("d:/mydata/a1.jpg");
try (FileInputStream in = new FileInputStream(file1);
FileOutputStream out = new FileOutputStream(file2);){
byte[] b = new byte[1024];
//使用流对文件进行读写
while(true){
int a = in.read(b);
if(a == -1) break;
out.write(b,0,a);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.2、缓冲字节流
文件字符流可以通过创建byte数组来手动创建缓冲区,但是java本身提供了缓冲字节流。为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缓冲流属于处理流,需要嵌套在节点流之上使用。
-
BufferedInputStream:缓冲输入流
FileInputStream in = new FileInputStream(file1); BufferedInputStream bufIn = new BufferedInputStream(in);
-
BufferedOutputStream:缓冲输出流
FileOutputStream out = new FileOutputStream(file2); BufferedOutputStream bufOut = new BufferedOutputStream(out);
它提供了带缓冲区的操作,一般打开文件进行写入或读取操作时,都会加上缓冲,这种流模式提高了IO的性能。把原本一个字节一个字节读取的流,加上了缓冲,相当于把字节存放到缓冲区,然后由缓冲区运送数据。
但是缓冲流本身不具有io流的读取写入功能,只是在别的流上加上缓冲的功能。它将数据放入缓冲区,然后缓冲区满后或者手动刷新后,在传输数据。
public class Io {
public static void main(String[] args) throws Exception{
//创建文件对象
File file1 = new File("d:/mydata/a.jpg");
File file2 = new File("d:/mydata/a1.jpg");
try (FileInputStream in = new FileInputStream(file1);
FileOutputStream out = new FileOutputStream(file2);
BufferedInputStream bufIn = new BufferedInputStream(in);
BufferedOutputStream bufOut = new BufferedOutputStream(out);){
//使用流对文件进行读写,缓冲流默认的byte长度为8192
while(true){
int a = bufIn.read();
if(a == -1) break;
bufOut.write(a);
bufOut.flush(); //手动刷新,让缓冲区的数据输出
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
4、字符流
Reader和Writer是所有字符输出/入类的父类,为抽象类,不能创建其实类,只能使用其子类。字符流以字符为操作单位,便于处理一些文本文件。
字符流在底层上其实还是对字节的操作
4.1、文件字符流
-
FileReader:文件字符输入流
FileReader in = new FileReader(file);
-
FileWriter:文件字符输出流
FileWriter out = new FileWriter(file); //每次都会把文件清空从写 FileWriter out = new FileWriter(file,true); //不会从写文件,而是在后面追加内容
它们是针对字符来进行操作的,主要用于处理纯字符集(纯文本)。和字节流不同的是,他只用于处理文本文件等以字符为单位的文件,而不能处理音频、图片等字节文件。
public class FileCharIOTest {
public static void main(String[] args) {
//读取文件内容
File readFile = new File("d:/mydata/text1.txt");
char[] chars = readFile(readFile);
System.out.println(chars);
//输出到文件
File writerFile = new File("d:/mydata/copytext1.txt");
writerFile(writerFile,chars);
}
//读取文件,输入流
public static char[] readFile(File file){
char[] chs = new char[(int) file.length()];
try (FileReader in = new FileReader(file)) {
while (true){
int read = in.read(chs);
if(read == -1) {
break; //为-1表示读取完毕
}
}
} catch (IOException e) {
e.printStackTrace();
}
return chs;
}
//写入文件,输出流
public static void writerFile(File file,char[] chars){
try (FileWriter out = new FileWriter(file)) {
out.write(chars);
} catch (IOException e) {
e.printStackTrace();
}
}
}
4.2、缓冲字符流
为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缓冲流属于处理流,需要嵌套在节点流之上使用。
-
BufferedReader:缓冲输入字符流
FileReader fr = new FileReader(file); BufferedReader in = new BufferedReader(fr);
-
BufferedWriter:缓冲输出字符流
FileWriter fw = new FileWriter(file); BufferedWriter out = new BufferedWriter(fw);
缓冲可以极大的提高了读写的速度。在缓冲字符流中提供了一种新的读写方法,其中BufferedReader提供了public Srting readLine();一次读取一行,到行标记时,将行标记之前的字符数据作为字符串返回。当读到末尾时,返回null。而BufferedWriter提供了public void newLine(); 写出平台相关的行分隔符来标记一行的终止。Windows平台下为’\n’。
readLine实际上是一个字符一个字符的读取,它将读取的字符append()到StringBuilder中,遇到换行符后,再转换成String输出。
public class Io {
public static void main(String[] args) throws Exception{
//创建文件对象
File file1 = new File("d:/mydata/a.txt");
File file2 = new File("d:/mydata/acopy.txt");
//创建缓冲流,对节点流进行包装
try (FileReader fr = new FileReader(file1);
FileWriter fw = new FileWriter(file2);
BufferedReader in = new BufferedReader(fr);
BufferedWriter out = new BufferedWriter(fw);){
String line;
//一次读取一行,读到换行时结束
while((line=in.readLine())!=null){
out.write(line);
out.write("\n"); //流不带换行,所以加上换行符,因为操作系统的不同所以可以用
//outout.newLine(); //提供自动换行的方法,不需要加换行符
}
out.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
}