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

分类

按照数据流的方向不同可以分为:输入流和输出流
按照处理数据单位不同可以分为:字节流和字符流
输入流、输出流都是从程序的角度来说的,输入流是指程序从文件获取数据,所以做的是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则删除后创建,缺省默认为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).字符流的过滤器:
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();
	}






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值