Java大数据开发和安全开发
- (一)Java的IO流文件读写
- 1.1 IO流前置知识
- 1.1.1 ASCII字符集
- 1.1.2 GBK字符集
- 1.1.3 Unicode字符集
- 1.1.4 UTF-8字符集
- 1.1.4 Java的编码解码
- 1.2 IO流的基础知识
- 1.2.1 认识I0流
- 1.2.2 应用场景
- 1.2.3 如何学I0流
- 1.2.3.1 先搞清楚I0流的分类、体系:
- 1.2.3.1 再挨个学习每个I0流的作用、用法。
- 1.2.3.1 字节流的用法
- 1.2.3.1.1 FilelnputStream文件字节输入流:每次读取一个字节
- 1.2.3.1.2 FilelnputStream文件字节输入流:每次读取多个字节
- 1.2.3.1.3 FilelnputStream文件字节输入流:一次读取完全部字节
- 1.2.3.1.4 FileOutputstream文件字节输出流:写字节出去
- 1.2.3.1.5 案例:文件复制
(一)Java的IO流文件读写
1.1 IO流前置知识
字符集、UTF-8、GBK、ASCII、乱码问题、编码和解码等
1.1.1 ASCII字符集
美国人发明了计算机以后就把自己的字符录入到系统中,也就是英文、数字、标点、特殊符号,但是计算机只能识别0、1,所以为了能使用这些字符,美国人发明了ASCII 将所用到字符编写为特定的编号,从0-127 ,这些被称为码点 然后把ASCII通过编码的方式写进计算机,也就是将编号0-127转换成二进制数表示,不够的补0,使用了一个字节来存储,
- 标准ASCII字符集 ASCll(American standard Code for Information Interchange):美国信息交换标准代码,包括了英文、符号等
- 标准ASCII使用1个字节存储一个字符,首尾是0,总共可表示128个字符
1.1.2 GBK字符集
GBK(汉字内码扩展规范,国标)
随着计算机的普及,中国将自己的字符编写成GBK汉字编码字符集,包含了2万多个汉字等字符,GBK中一个中文字符编码成两个字节的形式存储。
注意:GBK兼容了ASCII字符集。
ASCII首字节是0 GBK首字节是1
1.1.3 Unicode字符集
Unicode字符集(统一码,也叫万国码)
Unicode是国际组织制定的,可以容纳世界上所有文字、符号的字符集。
UTF-32 有容乃大,使用4个字节表示一个字符
不被使用的原因是比较奢侈!占存储空间,通信效率变低
1.1.4 UTF-8字符集
- 国际组织制定重新制定的,是Unicode字符集的一种编码方案,采取可变长编码方案,共分四个长度区:1个字节,2个字节,3个字节,4个字节
- 英文字符、数字等只占1个字节(兼容标准ASCII编码),汉字字符占用3个字节
注意:技术人员在开发时都应该使用UTF-8编码!
要点记忆部分
:
- ASCII字符集:只有英文、数字、符号等,占1个字节
- GBK字符集:汉字占2个字节,英文、数字占1个字节
- UTF-8字符集:汉字占3个字节,英文、数字占1个字节
注意1:字符编码时使用的字符集,和解码时使用的字符集必须一致,否则会出现乱码
注意2:英文,数字一般不会乱码,因为很多字符集都兼容了ASCII编码
1.1.4 Java的编码解码
- 编码:把字符按照指定字符集编码成字节。
- 解码:把字节按照指定字符集解码成字符。
import java.util.Arrays;public class ZiFu {public static void main(String[] args) throws Exception {// 1、编码String data ="a我b";byte[] bytes = data.getBytes();// 默认是按照平台字符集(UTF-8)进行编码的。System.out.println(Arrays.toString(bytes));// 按照指定字符集进行编码。byte[] bytes1 = data.getBytes( "GBK");System.out.println(Arrays.toString(bytes1));// 2、解码String s1= new String(bytes);// 按照平台默认编码(UTF-8)解码System.out.println(s1);// 按照指定字符集进行解码。String s2 =new String(bytes1,"GBK");System.out.println(s2);}
}
1.2 IO流的基础知识
1.2.1 认识I0流
IO流概述
- I指Input,称为输入流:负责把数据读到内存中去
- 0指Output,称为输出流:负责写数据出去
1.2.2 应用场景
1.2.3 如何学I0流
1.2.3.1 先搞清楚I0流的分类、体系:
- I0流的分类
总结流的四大类:
- 字节输入流:以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流
- 字节输出流:以内存为基准,把内存中的数据以字节写出到磁盘文件或者网络中去的流。
- 字符输入流:以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流。
- 字符输出流:以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络介质中去的流。
Java.io包下
- I0流的体系
1.2.3.1 再挨个学习每个I0流的作用、用法。
1.2.3.1 字节流的用法
1.2.3.1.1 FilelnputStream文件字节输入流:每次读取一个字节
FilelnputStream(文件字节输入流)
作用:以内存为基准,可以把磁盘文件中的数据以字节的形式读入到内存中去
import java.io.FileInputStream;
import java.io.InputStream;public class FileInputTest {public static void main(String[] args) throws Exception {// 1、创建文件字节输入流管道,与源文件接通。// InputStream is = new FileInputStream(new File("file-io-app\\src\\itheima01.txt"))// 简化写法:推荐使用。InputStream is = new FileInputStream(("file-io-app\\src\\itheima1.txt"));//2、开始读取文件的字节数据。// public int read():每次读取一个字节返回,如果没有数据了,返回-1.int b1 = is.read();System.out.println((char)b1);int b2 = is.read();System.out.println((char)b2);int b3 = is.read();System.out.println(b3);// 3、使用循环改造上述代码int b;// 用于记住读取的字节。while((b=is.read())!= -1) {System.out.print((char) b);}// 读取数据的性能很差!// 读取汉字输出会乱码!!无法避免的!!// 流使用完毕之后,必须关闭!释放系统资源!2is.close();}
}
1.2.3.1.2 FilelnputStream文件字节输入流:每次读取多个字节
import java.io.FileInputStream;
import java.io.InputStream;public class FileInputTest {public static void main(String[] args) throws Exception {InputStream is =new FileInputStream("/1.txt");// 2、开始读取文件中的字节数据:每次读取多个字节。// public int read(byte b[])throws IOException// 每次读取多个字节到字节数组中去,返回读取的字节数量,读取完毕会返回-1.byte[] buffer = new byte[3];int len = is.read(buffer);String rs=new String(buffer);System.out.println(rs);System.out.println("当次读取的字节数量:"+ len);// buffer = [abc]// buffer = [66c]int len2 = is.read(buffer);// 注意:读取多少,倒出多少。String rs2 = new String(buffer,0,len2);System.out.println(rs2);System.out.println("当次读取的字节数量:"+ len2);int len3 = is.read(buffer);System.out.println(len3);//-1}
}
优化代码
public class FileInputTest {public static void main(String[] args) throws Exception {InputStream is =new FileInputStream("lianxi\\src\\com\\qianxin\\file\\1.txt");// 2、开始读取文件中的字节数据:每次读取多个字节。// public int read(byte b[])throws IOException// 每次读取多个字节到字节数组中去,返回读取的字节数量,读取完毕会返回-1.// 3、使用循环改造。byte[] buffer = new byte[3];int len;// 记住每次读取了多少个字节。abc 66while((len=is.read(buffer))!=-1) {// 注意:读取多少,倒出多少。String rs = new String(buffer, 0, len);System.out.print(rs);}is.close();// 关闭流// 性能得到了明显的提升!!// 这种方案也不能避免读取汉字输出乱码的问题!!}
}
- 使用FilelnputStream每次读取多个字节,读取性能得到了提升,但读取汉字输出还是会乱码
1.2.3.1.3 FilelnputStream文件字节输入流:一次读取完全部字节
方式一:自己定义一个字节数组与被读取的文件大小一样大,然后使用该字节数组,一次读完文件的全部字节。
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通InputStream is =new FileInputStream("lianxi\\src\\com\\qianxin\\file\\1.txt");// 2、准备一个字节数组,大小与文件的大小正好一样大。File f = new File("lianxi\\src\\com\\qianxin\\file\\1.txt");long size = f.length();byte[] buffer =new byte[(int) size];int len = is.read(buffer);System.out.println(new String(buffer));System.out.println(size);System.out.println(len);}
}
lianxi\src\com\qianxin\file\1.txt 内容
public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通
1163
1163
方式二:Java官方为InputStream提供了如下方法,可以直接把文件的全部字节读取到一个字节数组中返回。
import java.io.FileInputStream;
import java.io.InputStream;public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通InputStream is =new FileInputStream("lianxi\\src\\com\\qianxin\\file\\1.txt");byte[] buffer = is.readAllBytes();System.out.println(new String(buffer));is.close();}
}
1、直接把文件数据全部读取到一个字节数组可以避免乱码,是否存在问题?
- 如果文件过大,创建的字节数组也会过大,可能引起内存溢出,
- 字符流:读写文本内容更适合用
- 字节流:适合做数据的转移,如:文件复制等
1.2.3.1.4 FileOutputstream文件字节输出流:写字节出去
FileOutputstream(文件字节输出流)
作用:以内存为基准,把内存中的数据以字节的形式写出到文件中去。
import java.io.FileOutputStream;
import java.io.OutputStream;public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通OutputStream os = new FileOutputStream("lianxi\\src\\com\\qianxin\\file\\1.txt");// 2、开始写字节数据出去了os.write(97); //97就是一个字节,代表aos.write('b'); //'b'也是一个字节os.write('磊');// [ooo]默认只能写出去一个字节byte[] bytes ="我爱你中国abc".getBytes();os.write(bytes);os.write(bytes,0,15);os.close();//关闭流}
}
写入文件不覆盖之前的内容
import java.io.FileOutputStream;
import java.io.OutputStream;public class FileInputTest {public static void main(String[] args) throws Exception {// 1、一次性读取完文件的全部字节到一个字节数组中去。// 创建一个字节输入流管道与源文件接通OutputStream os = new FileOutputStream("lianxi\\src\\com\\qianxin\\file\\1.txt",true);// 2、开始写字节数据出去了os.write(97); //97就是一个字节,代表aos.write('b'); //'b'也是一个字节os.write('磊');// [ooo]默认只能写出去一个字节byte[] bytes ="我爱你中国abc".getBytes();os.write(bytes);os.write(bytes,0,15);// 换行符os.write("\r\n".getBytes());os.close();//关闭流}
}