一、字符编码集
1.常用的字符编码
我们以前在notpad++中编写代码运行的时候,如果代码中有汉字,但是我们在编译的时候并没有使用-encoding UTF-8的时候就会出现乱码的现象。这是因为字符编码目的原因;因为不指定用什么样 的方式进行编码的时候,对于汉字就识别不了,这样的话就会出现错误。
那么接下来我们就介绍一下常见的编码到底有哪些:
(1)GBK、GB2312:表示的是国际编码,GBK包含简体中文和繁体中文,但是GB2312只包含简体中文。
(2)UNICODE编码:java提供的16进制编码,她可以描述任何一种文字信息;但是它也有缺点,16进制是两个字节,但是我们的字母是一个字节,在编码目的时候还是使用两个字节就会造成浪费。
(3)ISO8859-1:国际通过用编码,但是所有的编码需要进行转换。
(4)UTF编码:相当于结合了UNICODE、ISO8859-1,也就是说需要使用到16进制文字使用UNICODE,但是如果是字母就使用ISO8859-1编码,这样就不会造成浪费。常用的就是UTF-8。
2.乱码产生分析
//乱码分析
public class Test {
public static void main(String[] args) throws UnsupportedOperationException,IOException {
OutputStream out=new FileOutputStream(Paths.get("E:","learn","javaio","a1").toFile());
out.write("你好".getBytes("ISO8859-1"));
out.close();
}
}
之所以造成乱码,是因为在解码和编码使用的字符编码集不同。
二、内存操作流
1.内存流概念
内存操作流就是我们在进行I/O处理的时候对象是内存,就叫做内存流。前面我们学习的都是文件流,在文件流的操作中一定会产生一个文件数据(不管这个文件数据最后是否被保留)。
那我们的内存流一般处理的问题(出现的场景):当我们需要进行I/O文件处理但是我们不希望产生文件的时候就可以采用内存流了。
2.内存流分类
(1)字节内存流:
ByteArrayInputStream、ByteArrayOutputStream
(2)字符内存流:
CharArrayReader、CharArrayWriter
(3)
字节内存流输出流的构造方法:
public ByteArrayInputStream(byte buf[ ])
这个参数是字节型的数组,就是在进行读的时候将读出来的内容方法这个数组中。
字节内存流输入流的构造方法:
public ByteArrayOutputStream( )
3.内存流的继承关系
eg:通过内存流实现大小写转换
//通过内存流实现大小写的转换
public class TestMerry {
public static void main(String[] args) throws IOException {
String msg="hello world";
//通过内存实现小写转大写
InputStream input=new ByteArrayInputStream(msg.getBytes());//这一步的操作将msg的数据存到了内存中
OutputStream output=new ByteArrayOutputStream();//将内存中的数据写道文件中
int len=-1;
while((len=input.read())!=-1){//这个read()方法表示一次只读一个字节
//如果可以进入到这个说明还没有读完数据
//将读到的数据进行处理放到OutputStream类中
//边读编写,将读出来的字节经过转换以后写到文件中
output.write(Character.toUpperCase(len));
}
System.out.println(output);
input.close();
output.close();
}
}
这个时候 我们是通过I/O操作来实现了大小写的转换但是没有产生中间文件。
2.内存流操作
我们也可以通过内存流操作来实现两个文件的合并。
eg:现在将data1.txt、data2.txt进行合并处理
//将两个文件进行合并
public class TestAddFile {
public static void main(String[] args) throws IOException {
File[] files=new File[]{
new File("E:"+File.separator+"learn"+File.separator+"javaio"+File.separator+"data1.txt"),
new File("E:"+File.separator+"learn"+File.separator+"javaio"+File.separator+"data2.txt")
};
String[] data=new String[2];
for(int i=0;i<files.length;i++){
data[i]=readFile(files[i]);//这是我们自己定义的一个方法
}
StringBuffer buf=new StringBuffer();
String contentA[]=data[0].split(" ");
String contentB[]=data[1].split(" ");
for(int i=0;i<contentA.length;i++){
buf.append(contentA[i]).append("(").append(contentB[i]).append(")").append(" ");
}
System.out.println(buf);
}
private static String readFile(File file) throws IOException {
if(file.exists()){
InputStream input=new FileInputStream(file);
ByteArrayOutputStream bos=new ByteArrayOutputStream();
int len=-1;
byte[] data=new byte[10];
while((len=input.read(data))!=-1){
//将数据保存在bos中
bos.write(data,0,len);
}
bos.close();
input.close();
return new String(bos.toByteArray());
}
return null;
}
}
三、打印流
1.打印流的概念
我们之前要向一个文件输入信息的话用的是OutputStream,但是这个又缺陷:她要求所有的数据必须转换为字节数组,那么如果我们想要输出的是Int,double这些类型就不方便了。打印流就是为就解决这个问题的。
我们的System.out.println()可以输出任何类型的数据,下面我们自己来设计一个打印流,可以打印任意的基本数据类型。
//打印流
class PrintUtil {
private OutputStream out;
public PrintUtil(OutputStream out){
this.out=out;
}
//其核心功能就一个
public void print(String str){
try{
this.out.write(str.getBytes());
}catch(IOException e){
e.printStackTrace();
}
}
public void println(String str){
this.print(str+"\n");
}
public void print(int data){
this.print(String.valueOf(data));
}
public void println(int data){
this.print(String.valueOf(data));
}
public void print(double data){
this.print(String.valueOf(data));
}
public void println(double data){
this.print(String.valueOf(data));
}
}
public class Print{
public static void main(String[] args) throws FileNotFoundException {
PrintUtil p1=new PrintUtil(new FileOutputStream(new File("E:"+File.separator+"learn"+File.separator+"javaio"+File.separator+"data1.txt")));
p1.print(27);
p1.print("年号");
p1.print(10.25);
p1.println(15);
}
}
2.系统提供的打印流
打印流和我们的输入输出流一样,系统也是给我们提供的:(打印其本质就是往某个地方写内容)
(1)字节打印流:
PrintStream
(2)字符打印流:
PrintWriter
eg:使用我们的打印流实现输出:
//使用打印流输出
public class Print{
public static void main(String[] args) throws FileNotFoundException {
PrintWriter print1=new PrintWriter(new FileOutputStream(new File("E:"+File.separator+"learn"+File.separator+"javaio"+File.separator+"data1")));
print1.print(12);
print1.print('A');
print1.print(12.05);
print1.close();
}
}
3.格式化输出
这个和C语言的输出有些相似:
public PrintStream printf(String format,object … args)
eg:格式化输出
//格式化输出
public class Print{
public static void main(String[] args) throws FileNotFoundException {
String name="小明";
int age=20;
double salary=1000.23456;
PrintWriter printUtil=new PrintWriter(new FileOutputStream(new File("E:"+File.separator+"learn"+File.separator+"javaio"+File.separator+"data1.txt")));
printUtil.printf("姓名:%s,年龄:%d,工资:%1.4f",name,age,salary);
printUtil.close();
}
}
四、System类对I/O的支持
在这有一个面试的考点,需要掌握:
1.System.out.println()
System:表示一个类(java.lang.System)
out:表示一个对象
println():是PrintStream类的成员方法,是out对象的方法
2.System.in.read()
System:是一个类(java.lang.System)
in:是一个对象
read():是InputStream类的成员方法,是in对象的方法。
3.System.err.println()