分类
按照数据流的方向不同可以分为:输入流和输出流
按照处理数据单位不同可以分为:字节流和字符流
输入流、输出流都是从程序的角度来说的,输入流是指程序从文件获取数据,所以做的是read读取操作;输出流是指程序向文件传输数据,所以做的是write写入操作。
java.IO下有四大流抽象类:InputStream、OutputStream、Reader、Writer,其他流类都继承自这四大类
结构图:
结构图:
字节流和字符流的区别:
读写单位不同:字节流以字节(8bit)为单位,字符流以字符(16bit)为单位
处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据
结论:只要是处理纯文本数据,就优先考虑使用字符流,其他情况都使用字节流
处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据
结论:只要是处理纯文本数据,就优先考虑使用字符流,其他情况都使用字节流
1.字节流:
1).InputStream基本用法:
EOF= End 读到-1就读到结尾
int b = in.read(),读取一个字节无符号填充到int低八位
in.read(byte[] buf),读取数据填充到字节数组buf
in.read(byte[] buf, int start, int size),读取数据到字节数组buf,从buf的start
位置开始存放size长度的数据
2).OutputStream基本用法:
out.write(int b),写出一个字节到流,b的低八位
out.write(byte[] buf),将buf字节数组都写入到流
out.write(byte[] buf, int start, int size),字节数组buf从start位置开始写size长度的字节到流
3).FileInputStream/FileOutputStream --> 具体实现了在文件上读写数据
1).InputStream基本用法:
EOF= End 读到-1就读到结尾
int b = in.read(),读取一个字节无符号填充到int低八位
in.read(byte[] buf),读取数据填充到字节数组buf
in.read(byte[] buf, int start, int size),读取数据到字节数组buf,从buf的start
位置开始存放size长度的数据
2).OutputStream基本用法:
out.write(int b),写出一个字节到流,b的低八位
out.write(byte[] buf),将buf字节数组都写入到流
out.write(byte[] buf, int start, int size),字节数组buf从start位置开始写size长度的字节到流
3).FileInputStream/FileOutputStream --> 具体实现了在文件上读写数据
public class IOUtil {
/**
* 读取指定文件内容并按照16进制输出到控制台
*
* @param fileName
*/
public static void printHex(String fileName) throws Exception {
// 把文件作为字节流进行读操作
InputStream is = new FileInputStream(fileName);
int r;
while ((r = is.read()) != -1) {
// 讲整型r转换成16进制表示的字符串
System.out.print(Integer.toHexString(r) + " ");
}
is.close();
}
public static void printHexByByteArray(String fileName) throws Exception {
// 把文件作为字节流进行读操作
InputStream is = new FileInputStream(fileName);
byte[] buf = new byte[1 * 1024];
// 从is中批量读取字节,放入buf这个字节数组中,从第0个位置开始放,最多放buf.length个,返回的是读到的字节数
int bytes = 0;
while ((bytes = is.read(buf, 0, buf.length)) != -1) {
for (int i = 0; i < bytes; i++) {
System.out.print(Integer.toHexString(buf[i] & 0xff) + " ");
}
}
is.close();
}
public static void writeToFile(String fileName, boolean b) throws Exception {
// 如果文件不存在,直接创建,如果文件存在,删除后再创建
// OutputStream os = new FileOutputStream(fileName);
// 如果文件存在,b为true则在原文件后追加内容,b为false则删除后创建,缺省默认为false
OutputStream os = new FileOutputStream(fileName, b);
// write方法参考另一篇博文File类的使用中RandomAccessFile中的write方法
os.write('a');
os.close();
}
public static void main(String[] args) {
try {
// printHex("raf.dat");
// printHexByByteArray("raf.dat");
writeToFile("raf.dat", false);
printHex("raf.dat");
} catch (Exception e) {
e.printStackTrace();
}
}
}
结合使用:(字节批量读取拷贝)
public class FileStream {
public static void copyFile(File srcFile, File destFile) throws Exception {
if (!srcFile.exists()) {
throw new IllegalArgumentException("文件:" + srcFile + "不存在!");
}
FileInputStream is = new FileInputStream(srcFile);
FileOutputStream os = new FileOutputStream(destFile);
byte[] buf = new byte[1 * 1024];
int b;
while ((b = is.read(buf, 0, buf.length)) != -1) {
os.write(buf, 0, b);
os.flush();// 将缓冲区内容强制写出,避免文件未写完就关闭了
}
is.close();
os.close();
}
public static void main(String[] args) {
try {
copyFile(new File("raf.dat"), new File("rbf.dat"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
4).DataInputStream/DataOutputStream,可以更加方便的读写各种类型的数据
public class DataStream {
public static void main(String[] args) throws Exception {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(
"test.dat"));
dos.writeInt(10);
dos.writeLong(10l);
// 采用UTF-8编码格式写入
dos.writeUTF("你好");
// 采用java编码格式UTF-16be写入
dos.writeChars("你好");
dos.close();
DataInputStream dis = new DataInputStream(new FileInputStream(
"test.dat"));
int i = dis.readInt();
System.out.println(i);
long l = dis.readLong();
System.out.println(l);
String s = dis.readUTF();
System.out.println(s);
dis.close();
}
}
5).带缓冲的字节流BufferedInputStream/BufferedOutputStream
public static void copyFileByBuffer(File srcFile, File destFile)
throws Exception {
if (!srcFile.exists()) {
throw new IllegalArgumentException("文件:" + srcFile + "不存在!");
}
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
srcFile));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(destFile));
int c;
while ((c = bis.read()) != -1) {
bos.write(c);
}
bos.flush();// 将缓冲区内容强制写出,避免文件未写完就关闭了
bis.close();
bos.close();
}
public static void main(String[] args) {
try {
copyFileByBuffer(new File("raf.dat"), new File("raf2.dat"));
} catch (Exception e) {
e.printStackTrace();
}
}
6).字符流(Reader、Writer):
·字符的处理,一次处理一个字符
·字符的底层依然是基本的字节序列
基本实现:
InputStreamReader 完成byte流解析为char流,按照编码解析
OutputStreamwriter 提供char流到byte流,按照编码处理
public static void main(String[] args) throws Exception {
// TODO 自动生成的方法存根
InputStream is = new FileInputStream("raf.dat");
// 设置为要操作的文件的编码格式,默认为项目编码
InputStreamReader isr = new InputStreamReader(is, "utf-8");
OutputStream os = new FileOutputStream("test.dat");
OutputStreamWriter osw = new OutputStreamWriter(os);
// int c = 0;
// while ((c = isr.read()) != -1) {
// System.out.print((char) c);
// }
int b;
char[] buffer = new char[1 * 1024];
while ((b = isr.read(buffer, 0, buffer.length)) != -1) {
// for (int i = 0; i < b; i++) {
// System.out.print(buffer[i]);
// }
String s = new String(buffer, 0, b);
System.out.print(s);
osw.write(buffer, 0, b);
}
osw.flush();
isr.close();
osw.close();
}
7).FileReader/FileWriter:
public static void main(String[] args) throws Exception {
// TODO 自动生成的方法存根
FileReader fr = new FileReader("test.dat");
FileWriter fw = new FileWriter("test2.dat");
int c;
char[] buffer = new char[1 * 1024];
while ((c = fr.read(buffer, 0, buffer.length)) != -1) {
fw.write(buffer, 0, c);
}
fw.flush();
fr.close();
fw.close();
}
值得注意的是,FileReader/FileWriter不能对编码进行指定,如果发生乱码问题建议还是使用InputStreamReader/OutputStreamWriter
8).字符流的过滤器:
8).字符流的过滤器:
BufferedReader --> readLine 一次读一行
BufferedWriter/PrintWriter --> 一次写一行
BufferedWriter/PrintWriter --> 一次写一行
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream("rbf.dat")));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("rbf2.dat")));
// PrintWriter pw = new PrintWriter("rbf.txt");
String s;
while ((s = br.readLine()) != null) {
System.out.println(s);// 一次读一行,不能识别换行
bw.write(s);
// 要手动进行换行操作
bw.newLine();
// pw.println(s);
}
bw.flush();
// pw.flush();
br.close();
bw.close();
// pw.close();
}