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

来源:互联网 发布:java 多租户 编辑:程序博客网 时间:2024/06/04 20:34

------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
原创粉丝点击