黑马程序员--Java基础--IO流(二)

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、文件加密

原理:读取文件,将每次读取的字节异或特定密码,得到加密密文存入定义好的集合直到读取所有字节结束;将密文存回原文件,完成文件加密。要将文件解密只需再次异或特定密码即可。

package it.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class IOTest1 {

	public static void main(String[] args) throws IOException {
		List<Integer> list = new ArrayList<Integer>(); //定义一个集合,用来装载文件数据
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("F:\\file.txt"));//定义输入流
		int b;
		while((b = bis.read()) != -1)//逐个字节读取文件中的内容
			list.add(b^123);//将文件中的每个字节异或密码,得到密文,将密文存入集合
		bis.close();
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("F:\\file.txt"));//定义输出流
		for (Integer i : list) //直到读取所有字节结束,将集合中存储的数据写回文件
			bos.write(i);
		bos.close();
	}
}

二、字节流读写中文

1、 FileInputStream读取中文

逐个字节读取无法显出中文,因为中文(GBK)有2个字节组成(utf-8中文3个字节)。所以要读取中文就要判断读取的是否为中文字节,如果是就要一次读取2个字节输出。

InputStream.read()方法是读一个byte,而返回一个int(int中全是正数)。因为byte取值范围是-128到127,这些数据在文件中都可能存在,如果读到字节直接返回,那么无法用任何一个值表示文件末尾。

read()方法内部,将读取到的所有数据高位补0转为int(数据与255),这样将所有负数都转为正数。

FileInputStream 只能读取字节,要读取中文需人工解码

package it.io;

import java.io.FileInputStream;
import java.io.IOException;

public class IOTest2 {

	public static void main(String[] args) throws IOException {
		//使用FileInputStream每次读取一个字节,人工解码读取中文
		FileInputStream fis = new FileInputStream("F:\\file.txt");
		int b;
		while((b = fis.read()) != -1) {
			byte b1 = (byte) b;
			if (b1 < 0) {	//如果读取到了负数(代表遇到中文),再多读一个,两个一起转为一个字符
				byte b2 = (byte) fis.read();
				System.out.print(new String(new byte[]{b1, b2}));
			}else {			//如果读到的不是负数,直接转为字符
				System.out.print((char) b);
			}
		}
		fis.close();
	}

}

2、 FileOutputStream写出中文

write() 方法写出数据时,会将int 数据强转为byte,在写出,这样就把read()方法中补得0都去掉了,得到了文件中原有数据。

FileOutputStream 只能写出字节,要写出中文需人工编码

package it.io;

import java.io.FileOutputStream;
import java.io.IOException;

public class IOTest2 {

	public static void main(String[] args) throws IOException {
		//使用FileOutputStream只能写出一个字节,写中文要人工编码
		FileOutputStream fos = new FileOutputStream("F:\\file.txt");
		fos.write("你好!".getBytes());
		fos.write("你吃饭了吗?".getBytes());
		fos.close();
	}
}

三、字符流读写中文

1、 InputStreamReader读取中文

InputStreamReader包装一个InputStream, 可以直接读取字符, 自动解码

package it.io;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class IOTest3 {

	public static void main(String[] args) throws IOException {
		InputStreamReader isr = new InputStreamReader(new FileInputStream("F:\\file.txt"));//字符输入流
		int b;
		while ((b = isr.read()) != -1)	//每次读取一个字符,内部自动解码,遇到英文读1个字节转为字符,遇到中文读2个字节转为字符
			System.out.println((char) b);
		isr.close();
	}
}

2、 OutputStreamWrite写出中文

OutputStreamWriter包装一个OutputStream, 可以直接写出字符, 自动编码

package it.io;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class IOTest3 {

	public static void main(String[] args) throws IOException {
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("F:\\file.txt"));//字符输出流
		osw.write("你好!");
		osw.write("你吃饭了吗? ");
		osw.close();
	}
}
<span lang="EN-US" style="background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">3、<span style="font-size: 7pt; font-family: 'Times New Roman';"> </span></span><span style="text-indent: -18pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">指定码表读写字符</span>
<span style="background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">在使用</span><span lang="EN-US" style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">InputStreamReader</span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">和</span><span lang="EN-US" style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">OutputStreamWriter</span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">的时候,如果希望读写非平台默认码表,需在构造函数中可以指定</span>
<span style="background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;"><span style="white-space:pre">	</span>指定</span><span lang="EN-US" style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">UTF-8</span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">码表解码读取字符:</span>
package it.io;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class IOTest3 {

	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("F:\\file.txt");
		InputStreamReader isr = new InputStreamReader(fis, "UTF-8");//指定用UTF-8解码
		int b; 
		while ((b = isr.read()) != -1)
			System.out.print((char) b);
		isr.close();//关闭isr时会自动关闭fis
	}
}

指定UTF-8码表编码写出字符:

package it.io;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class IOTest3 {

	public static void main(String[] args) throws IOException {
		FileOutputStream fos = new FileOutputStream("F:\\file.txt");
		OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");//指定使用UTF-8码表编码
		osw.write("你好!");
		osw.write("你吃饭了吗? ");
		osw.close();
	}
}
<span lang="EN-US" style="background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">4、<span style="font-size: 7pt; font-family: 'Times New Roman';"> </span></span><span lang="EN-US" style="text-indent: -18pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">FileReader</span><span style="text-indent: -18pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">和</span><span lang="EN-US" style="text-indent: -18pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">FileWriter</span>
<span lang="EN-US" style="background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">FileReader</span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">是</span><span lang="EN-US" style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">InputStreamReader</span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">的子类</span><span lang="EN-US" style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">, </span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">在读取平台默认码表的文件时</span><span lang="EN-US" style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">, </span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">可以使用</span><span lang="EN-US" style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">FileReader</span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">替代</span><span lang="EN-US" style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">InputStreamReader</span>
<span lang="EN-US" style="background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">FileWriter</span><span style="text-indent: 1pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">是</span><span lang="EN-US" style="text-indent: 1pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">OutputStreamWriter</span><span style="text-indent: 1pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">的子类</span><span lang="EN-US" style="text-indent: 1pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">, </span><span style="text-indent: 1pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">在写出平台默认码表的文件时</span><span lang="EN-US" style="text-indent: 1pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">, </span><span style="text-indent: 1pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">可以使用</span><span lang="EN-US" style="text-indent: 1pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">FileWriter</span><span style="text-indent: 1pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">替代</span><span lang="EN-US" style="text-indent: 1pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">OutputStreamWriter</span>
package it.io;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class IOTest4 {

	public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader("F:\\file.txt");//使用平台默认码表读取文件
		int b;
		while ((b = fr.read()) != -1)
			System.out.print(b);
		fr.close();
		FileWriter fw = new FileWriter("F:\\file1.txt");//使用平台默认码表写出文件
		fw.write("你好!");
		fw.write("你吃饭了吗?");
		fw.close();
	}

}
<span lang="EN-US" style="background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">5、<span style="font-size: 7pt; font-family: 'Times New Roman';"> </span></span><span lang="EN-US" style="text-indent: -18pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">BufferedReader</span><span style="text-indent: -18pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">和</span><span lang="EN-US" style="text-indent: -18pt; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">BufferedWriter</span>
<span lang="EN-US" style="background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">BufferedReader</span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">可以包装一个</span><span lang="EN-US" style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">Reader, </span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">提供缓冲功能</span><span lang="EN-US" style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">, </span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">而且提供了</span><span lang="EN-US" style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">readLine()</span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">方法可以读取一行字符</span>
<span lang="EN-US" style="background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">BufferedWriter</span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">可以包装一个</span><span lang="EN-US" style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">Writer, </span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">提供缓冲功能</span><span lang="EN-US" style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">, </span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">而且提供了</span><span lang="EN-US" style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 'Courier New';">newLine()</span><span style="text-indent: 0cm; background-color: rgb(255, 255, 255); font-size: 10pt; font-family: 宋体;">方法写出系统对应的换行符号</span>
package it.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class IOTest4 {

	public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader("F:\\file.txt");
		BufferedReader br = new BufferedReader(fr);
		int b;
		while ((b = br.read()) != -1){
			System.out.print(b);
			br.readLine();//匹配操作系统的换行符号
		}
		br.close();
		FileWriter fw = new FileWriter("F:\\file1.txt");
		BufferedWriter bw = new BufferedWriter(fw);
		bw.write("你好");
		bw.newLine();//匹配操作系统的换行符号
		bw.write("你吃饭了吗?");
		bw.close();
	}
}

四、小结

1.使用FileInputStream和FileOutputStream读写中文

FileInputStream只能读取字节, 如果希望读取字符, 需要人工解码

FileInputStream只能读取字节, 如果希望读取字符, 需要人工解码

2.使用InputStreamReader和OutputStreamWriter读写中文

                   InputStreamReader包装一个InputStream, 可以直接读取字符, 自动解码

                   OutputStreamWriter包装一个OutputStream, 可以直接写出字符, 自动编码

3.指定码表读写字符                                         

在使用InputStreamReader和OutputStreamWriter的时候, 在构造函数中可以指定读写非平台默认码表。

4.FileReader和FileWriter

FileReader是InputStreamReader的子类, 在读取平台默认码表的文件时, 可以FileReader替代InputStreamReader

FileWriter是OutputStreamWriter的子类, 在写出平台默认码表的文件时, 可以使用FileWriter替代OutputStreamWriter

5.BufferedReader和BufferedWriter

BufferedReader可以包装一个Reader, 提供缓冲功能, 而且提供了readLine()方法可以读取一行字符

BufferedWriter可以包装一个Writer, 提供缓冲功能, 而且提供了newLine()方法写出系统对应的换行符号

6.LineNumberReader

是BufferedReader的子类, 带有缓冲功能, 可以读取一行, 并且还能统计行号

------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值