1. 流的概念
流是一组有顺序的,有起点和终点的字节集合。
2. 流的分类
按处理数据的类型分为字节流和字符流
按数据流向分为输入流和输出流
字节流和字符流的区别
字节流一次只读取一个字节,字符流一次读取一个字符(一个字符包含多个字节)。字节流可以所有类型的数据,而字符流只能处理字符类型的数据(如文本文件)
字节流
InputStream,抽象了应用程序读取数据的方式
OutputStream ,抽象了应用程序写出数据的方式
输入流的基本方法
InputStream in = new InputStream();
int b = in.read();
读取一个字节无符号填充到int的最后8位,返回的是读到的字节(转换成int类型的值的)内容,当读到-1时,标识读取到最后结束了。
in.read(byte[] buf);
读取的数据填充到字节数组buf中,返回的是读到的字节的个数。
in.read(byte[] buf,int start ,int size);
读取数据到字节数组buf,并且是从buf的start位置开始,最多存放size长度的数据,返回的是读到的字节的个数。
输出流的基本方法
OutputStream out = new OutputStream();
out.write(int b);
写出一个字节到流,写的是int的最后的8位
out.write(byte[] buf);
将buf字节数组都写入到流
out.write(byte[] buf,int start,int size);
字节数组buf从start位置开始写size长度的字节到流
字节流的实现类
文件输入输出流
FileInputStream FileOutputStream
数据输入输出流
DataInputStream DataOutputStream
加了一些方法如writeInt(),writeLong()等等,普通的流只有writre(),即只能写入字节
字节缓冲流
BufferedInputStream BufferedOutputStream
为IO流加入缓冲,提高了读写的性能
带缓冲要在out.write()后加out.flush(); flush()表示强制将缓冲区中的数据发送出去,不必等到缓冲区满.
实验证明,批量读写速度最快(通过byte[]来作为缓冲区),比带缓冲的快很多
字符流
Reader,读取字符的抽象基类
Writer,写入字符的抽象基类
字符流和字节流的方法差不多,只不过读取的单位不同,读取单位指的是read和write方法中参数的类型
字符流的实现类
InputStreamReader,完成byte流解析为char流,按照编码解OutputStreamReader,提供char流到byte流,按照编码处理
注意:
假设文本文件的编码格式为gbk,项目的工作空间编码是utf-8
InputStreamReader isr=new InputStreamReader(in)
此时读出的数据会乱码,因为默认是按照项目的编码进行解析的
InputStreamReader isr=new InputStreamReader(in,“charset”)
将charset写为gbk,则不会出现乱码问题
读取单位是char
文件的读写
FileReader/FileWriter
读取单位char或者string
字符缓冲流
BufferedReader
BufferedWriter
3. File类和RandomAccessFile类
读写 rw 只读r
File
将文件和文件夹抽象成类的形式
RandomAccessFile
可以从文件指定的位置读取数据
4. 代码体现IO流的各种操作
文件复制
private static void copyFile() {
String sPath = "/Users/sufan/Desktop/szsmk说明.txt";
String dPath = "/Users/sufan/Desktop/copyszsmk.txt";
File sFile = new File(sPath);
File dFile = new File(dPath);
if(!sFile.exists()){
System.out.println("源文件不存在");
return;
}
//这句代码有无均可
if (!dFile.exists()) {
try {
dFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
FileInputStream fis = new FileInputStream(sFile);
FileOutputStream fos = new FileOutputStream(dFile);
byte[] bytes = new byte[512];
int rs = -1;
while ((rs = fis.read(bytes)) > 0) {
fos.write(bytes, 0, rs);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
文件夹复制
private static void copyFileDir() {
String sPath = "/Users/sufan/Desktop/javaTest";
String dPath = "/Users/sufan/Desktop/copyJavaTest";
File sFile = new File(sPath);
File dFile = new File(dPath);
if(!sFile.exists()){
System.out.println("源文件夹不存在");
return;
}
//此处可有可无
if (!dFile.exists()) {
dFile.mkdir();
}
File[] files = sFile.listFiles();
copyFileChild(files, dFile);
}
// 循环遍历复制文件夹中的内容(文件夹和文件)
private static void copyFileChild(File[] sFiles, File dFile) {
for (int i = 0; i < sFiles.length; i++) {
if (sFiles[i].isFile()) {
try {
FileInputStream fis = new FileInputStream(sFiles[i]);
FileOutputStream fos = new FileOutputStream(
new File(dFile.getAbsolutePath() + "/"
+ sFiles[i].getName()));
byte[] bytes = new byte[512];
int rs = -1;
while ((rs = fis.read(bytes)) > 0) {
fos.write(bytes, 0, rs);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if (sFiles[i].isDirectory()) {
String dPath = dFile.getAbsolutePath() + "/"
+ sFiles[i].getName();
System.out.println(dPath);
File df = new File(dPath);
if (!df.exists()) {
df.mkdir();
}
File[] sf = sFiles[i].listFiles();
copyFileChild(sf, df);
}
}
}
同样删除操作也分为文件和文件夹
等等还有很多操作在这里我就不一一列出代码了