小白成长记——Java基础之I/O流

来源:互联网 发布:西川贵教 知乎 编辑:程序博客网 时间:2024/06/06 03:30

分类

按照数据流的方向不同可以分为:输入流和输出流
按照处理数据单位不同可以分为:字节流和字符流
输入流、输出流都是从程序的角度来说的,输入流是指程序从文件获取数据,所以做的是read读取操作;输出流是指程序向文件传输数据,所以做的是write写入操作。

java.IO下有四大流抽象类:InputStream、OutputStream、Reader、Writer,其他流类都继承自这四大类
结构图:

字节流和字符流的区别:

读写单位不同:字节流以字节(8bit)为单位,字符流以字符(16bit)为单位
处理对象不同:字节流能处理所有类型的数据(如图片、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 --> 具体实现了在文件上读写数据
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则删除后创建,缺省默认为falseOutputStream 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).字符流的过滤器:
BufferedReader --> readLine 一次读一行
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();}






原创粉丝点击