Java基础(20,21)IO流

来源:互联网 发布:云南大学软件学院图片 编辑:程序博客网 时间:2024/06/05 16:34

二十八.IO流列出目录下所有内容-递归


import java.io.*;class IoTextDemo{public static void main(String[] args){//开始名字写错了,返回nullFile dir = new File("E:\\JAVA_TEXT"); //System.out.println(dir);//打印的是E:\\JAVA_TEST//System.out.println(dir);showDir(dir,0);}public static String getLevel(int level){StringBuilder sb = new StringBuilder();sb.append("|--");for(int i = 0;i<level;i++){sb.insert(0 ,"|  ");}return sb.toString();}public static void showDir(File dir,int level){System.out.println(getLevel(level)+dir.getName());level++;File[] filelist =dir.listFiles();//System.out.println(dir);//显示主目录的名字for(int i = 0;i<filelist.length;i++){if(filelist[i].isDirectory())//如果读到的是一个目录,就继续往里面读{showDir(filelist[i],level);}else //不是目录是文件{System.out.println(filelist[i]);//这个地方不写层级,//只有目录会有| ,文件前面没有//System.out.println(getLevel(level)+filelist[i]);}}}}

二十九.IO流删除带内容的目录

删除原理:
在window中,删除目录从里面往外删除的。
既然从里往外删除。就需要用到递归

import java.io.*;class IoTextDemo{public static void main(String[] args){File dir = new File("E:\\JAVA_TEXT");removeDir(dir);}public static void removeDir(File dir){File[] files = dir.listFiles();for(int i = 0;i<files.length;i++){if(files[i].isDirectory()){removeDir(files[i]);//如果是目录继续往里走,看看是不是目录,知道找到文件然后删除}else{//如果打印false ,就说明一个文件夹被删了两次System.out.println(files[i].toString()+"-file-"+files[i].delete());}}System.out.println(dir+"::"+dir.delete());//删除文件}}

三十.IO流创建java文件列表,   前面有一个用listFile做的,可以对比一下

练习
将一个指定目录下的java文件的绝对路径,存储到一个文本文件中。
建立一个Java文件列表文件。


思路:
1.对指定的目录进行递归。
2.获取递归过程所有的java文件的路径
3.将这些路径存储到集合中,存入list!!!!
4.将集合中的数据写入到一个文件中

import java.io.*;import java.util.*;class IoTextDemo{public static void main(String[] args) {File dir = new File("E:\\JAVA_TEXT");//FileWriter fw = new FileWriter("E:\\list_document.txt");File f = new File("E:\\list_java.txt");//看看f打印什么File f1 = new File("E:\\玩玩.txt");try{System.out.println(f);  //打印出E:\list_java.txt   //这个文件存在System.out.println(f1); //打印出E:\玩玩.txt  //这个文件并不存在}catch (Throwable e){throw new RuntimeException("cuo");}ArrayList<File> alist = new ArrayList<File>();fileAddToList(dir,alist); //把文件信息存到集合中writeTofile(alist ,f.toString());  //从集合中把信息写到文件上}public static void fileAddToList(File dir ,ArrayList<File> list ){File[] files = dir.listFiles();//高级for循环取数据//for(File file : files)//{//if(file.isDirectory())//{//fileToList(file ,list);//}//else//{//if(file.getName().endsWith(“.java”))//list.add(file);//}//}//传统for循环for(int i = 0;i<files.length;i++){if(files[i].isDirectory()) //如果是目录就继续进去{fileAddToList(files[i],list);}else //如果是文件就添加进list集合{if(files[i].getName().endsWith("java"))list.add(files[i]);}}}public static void writeTofile(ArrayList<File> list , String file){FileWriter fw = null;BufferedWriter bufw = null;try{fw = new FileWriter(file);bufw = new BufferedWriter(fw);//高级for循环取出数据//for(File f:list)//{//String path = f.getAbsolutePath();//bufw.write(path);//bufw.newLine();//bufw.flush();//}//用迭代器取出数据Iterator<File> it = list.iterator();  //这里开始写错了while(it.hasNext()){File fi = it.next();String filepath = fi.getAbsolutePath();bufw.write(filepath);bufw.newLine();bufw.flush();}}catch (Throwable e){throw new RuntimeException("错误1");}finally{try{if(bufw !=null){bufw.close();}}catch (Throwable e){throw new RuntimeException("错误2");}}}}


三十一.IO流Properties

//properties是hashtable的子类
//也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串。
//是集合中和IO技术相结合的结合容器。
//该对象的特点:可以用于键值对形式的配置文件。
//那么在加载数据时,需要数据有固定的格式,通常键 = 值。


import java.io.*;import java.util.*;class IoTextDemo{public static void main(String[] args) throws IOException{//setAndGet();method_1();}public static void setAndGet(){Properties prop = new Properties();//setProperty(String key, String value),调用Hashtable的put方法prop.setProperty("zhangsan","30");prop.setProperty("lisi","39");System.out.println(prop);//stringPropertyNames()返回此属性列表中的键集,//其中该键及其对应值是字符串,如果在主属性列表中未找到同名的键,//则还包括默认属性列表中不同的键。String value = prop.getProperty("lisi");System.out.println(value);Set<String> names = prop.stringPropertyNames();prop.setProperty("lisi",89+"");//改变元素的值//改变值for(String  s : names){System.out.println(s+":"+prop.getProperty(s)); //获取key}}//代码2//演示,如何将流中的数据存储到集合中。//想要将info.txt中键值数据存到集合中进行操作。//1.用一个流和info.txt文件关联。//2.读取一行数据,将该行数据用”=”进行切割。//3.等号左边作为键,右边作为值。存入到Properties集合中即可。public static void method_1() throws IOException{BufferedReader bufr = new BufferedReader(new FileReader("E:\\SYSTEM_INFO.txt"));String line = null;Properties prop = new Properties();while((line = bufr.readLine()) != null){String[] arr = line.split("=");System.out.println(arr[0]+"---"+arr[1]);prop.setProperty(arr[0],arr[1]);}bufr.close();System.out.println(prop);}///代码3(优化代码2)public static void loadDemo() throws IOException //跟下面的功能一样,只是更简单了{Properties prop = new Properties();FileInputStream fis = new FileInputStream(“info.txt”);//将流中的数据加载进集合。从输入流中读取属性列表(键和元素对)。prop.load(fis);//System.out.println(prop);//和下面的效果一样 把键和值成对打印//prop.list(System.out);//和上面的效果一样//之前是99,这里改成39,打印出39,但是文件中还是99prop.setProperty(“wangwu”,”39”); / /只是改变了内存中值,源头没改变,如果要改变需要存起来//store是将内存中的数据(也就是上面的setProperty的数据)先存到流中,然后存到文件中,会打印时间FileOutputStream  fos = new FileOutputStream(“info.txt”);prop.store(fos.”haha”);//haha是注释fos.close();fis.close();}}

三十二.IO流Properties练习

//用于记录应用程序运行次数。
//如果使用次数已到,那么给出注册提示。
//很容易想到的是:计数器
//可是该计数器定义在程序中,随着程序的运行而在内存中存在,并自行自增
//可是随着该应用程序的退出,该计数器也在内存中消失了。

//下一次在启动该程序,又重新开始从0计数。
//这样不是我们想要的。
//程序即时结束,该计数器的值也存在。
//下次程序启动时会先加载该计数器的值并加1后再重新存储起来。

//所以要建立一个配置文件。用于记录该软件的使用次数。

//该配置文件使用键值对的形式。
//这样便于阅读数据,并操作数据。

//键值对数据是map集合
//数据是以文件形式存储,使用io技术
//那么map+io-->properties

//配置文件可以实现应用程序数据的共享

import java.io.*;import java.util.*;class IoTextDemo{public static void main(String[] args) throws IOException{File file = new File("E:\\count.txt");Properties pro = new Properties();if(!file.exists()){file.createNewFile(); //如果不存在就创建一个}FileInputStream fis = new FileInputStream(file);pro.load(fis);int count = 0;String value = pro.getProperty("time");if(value == null){count++;pro.setProperty("time",count+"");}else{count = Integer.parseInt(value); //如果没有这个,那么count每次进来都是0!!!count ++;pro.setProperty("time",count+"");if(count >4){System.out.println("到期,请续费");}}FileOutputStream fos = new FileOutputStream(file); //改变了数据就要存到file文件中pro.store(fos,"");fos.close();fis.close();}}

三十三.IO流printWriter

PrintWriter与PrintStream
可以直接操作输入流和文件
打印流:
该流提供了打印方法,可以将各种数据类型的数据都原样打印!!!

字节打印流:
PrintStream
构造函数可以接受的参数类型:
1.file对象。File
2.字符串路径。String
3.字节输出流。OutputStream(控制台对应的对象时是字节输出流)

字符打印流:
PrintWriter
构造函数可以接受的参数类型:
1file对象。File
2字符串路径。String
3字节输出流。OutputStream
4.字符输出流,Writer (跟上面的差别所在)

PrintWriter(OutputStream out , boolean auto Flush)
out - 输出流
autoFlush - boolean变量;如果为true ,则println,printf或format方法将刷新输出缓冲区

import java.io.*;class IoTextDemo{public static void main(String[] args) throws IOException{BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//控制台输出//PrintWriter out = new PrintWriter(System.out , true);//如果把输出写入一个文件时,不能写true,因为针对的是流,才能自动刷新//PrintWriter out = new PrintWriter("E:\\20150405text2.txt");//把写入文件也弄成自动刷新//和上面的区别在于,输入完之后,不用over,文件就自动生成大写PrintWriter out = new PrintWriter(new FileWriter("E:\\20150405text4.txt"),true);String line = null;while((line = bufr.readLine()) != null){if("over".equals(line)){break;}//如果new PrintWriter(System.out , true);不写true,那么输入小写之后不会立即显示写,因为在缓冲区中//没有刷新,over之后才会全部出来。如果有true,写一个对应的大写就出来了,自动刷新out.println(line.toUpperCase());}out.close();bufr.close();}}

三十四.IO合并流

//把三个流放一起,然后再写在一个文件里(分别读取三个文件存到一个,要考虑续写问题,多个源对应一个目的)
//这里直接把多个源,变成一个源

import java.io.*;import java.util.*;class IoTextDemo{public static void main(String[] args) throws IOException{Vector<FileInputStream> v = new Vector<FileInputStream>();v.add(new FileInputStream("E:\\hebing\\1.txt"));v.add(new FileInputStream("E:\\hebing\\2.txt"));v.add(new FileInputStream("E:\\hebing\\3.txt"));Enumeration<FileInputStream> en = v.elements();//SequenceInputStream(Enumeration<? extends InputStream> e) //通过记住参数来初始化新创建的 SequenceInputStream,//该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。SequenceInputStream sis = new SequenceInputStream(en);FileOutputStream fos = new FileOutputStream("E:\\hebing\\4.txt");byte[] buf = new  byte[1024];int len = 0;//read(char[] cbuf)//public int read(byte[] b)//从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。//在某些输入可用之前,此方法将阻塞。while((len = sis.read(buf)) != -1){fos.write(buf,0,len);}fos.close();sis.close();}}

三十五.IO流切割文件

import java.io.*;import java.util.*;class IoTextDemo{public static void main(String[] args)throws IOException{//splitdocu();sequenceInput();}public static void splitdocu() throws IOException{FileInputStream fis = new FileInputStream("E:\\hebing\\w.jpeg");FileOutputStream fos = null;byte[] buf = new byte[1024*15];int len = 0;int count = 0;while((len = fis.read(buf)) != -1){count++;fos = new FileOutputStream("E:\\hebing\\"+count+".jpeg");fos.write(buf,0,len);}fis.close();fos.close();}public static void sequenceInput()throws IOException{ArrayList<FileInputStream> list = new ArrayList<FileInputStream>();for(int i = 1;i<4;i++){list.add(new FileInputStream("E:\\hebing\\"+i+".jpeg")); //会报错,FileInputStream 无法转为String}final Iterator<FileInputStream> it = list.iterator();//为什么要这么写,这个真不明白,因为只有Iterator有hasNext和next,Iterator跟Enumeration功能是一样的//方法摘要// boolean hasMoreElements()测试此枚举是否包含更多的元素// E nextElement()如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。Enumeration<FileInputStream> en = new Enumeration<FileInputStream>(){public boolean hasMoreElements(){return it.hasNext();}public FileInputStream nextElement(){return it.next();}};SequenceInputStream sis = new SequenceInputStream(en);FileOutputStream fos = new FileOutputStream("E:\\hebing\\f.jpeg");int len = 0;byte[]  buf = new byte[1024];while((len = sis.read(buf)) != -1){fos.write(buf,0,len);}fos.close();sis.close();}}

三十六.IO包中其他类

打印流
PrintWriter与PrintStream
可以直接操作输入流和文件

序列流
SequenceInputStream
对多个流进行合并

操作对象 ,也就把堆内存中的对象存到文件中去,这个是他的重点!!!!!(硬盘),ObjectInputStream 与ObjectOutStream,被操作的对象需要实现Serializable(标记接口)
ObjectOutputStream 和 ObjectInputStream 分别与 FileOutputStream 和 FileInputStream 一起使用时,可以为应用程序提供对对象图形的持久存储(即把对象存到文件中),ObjectInputStream 用于恢复那些以前序列化的对象。其他用途包括使用套接字流在主机之间传递对象,或者用于编组和解组远程通信系统中的实参和形参。

import java.io.*;class IoTextDemo{public static void main(String[] args) throws Exception{///writeObj();readObj();}public static void readObj() throws Exception{ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\hebing\\obj.txt"));Person p = (Person)ois.readObject();System.out.println(p);ois.close();}public static void writeObj() throws IOException{ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\hebing\\obj.txt"));//oos.writeObject(new Person("lisi",39));//按理说new person(“lisi”,39)是应该在堆内存当中,这里就都存在对象当中,//想把对象写在硬盘上(文件中)(用方法writeObject)oos.writeObject(new Person("lisi",39,"kr"));//lisi:39:cn//只能把堆里面的序列化,//不能把方法区里面的序列化oos.close();}}

三十七.IO流RandomAccessFile

RandomAccessFile,该类不算是IO体系种子类,而是直接继承自Object。

但是它是IO包中成员。因为它具备读和写功能,内部封装一个数组,而且通过指针对数组的元素进行操作,可以通过getFilePointer获取指针位置。
同时可以通过seek改变指针的位置

其实完成读写的原理就是内部封装了字节输入流和输出流。
通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式,只读R,读写rw等。

如果模式为只读r,不会创建文件,会去读取一个已存在文件,如果该文件不存在,则会出现异常(R),而且该对象的构造函数要操作的文件不存在,会自动创建,如果存在则不会覆盖(W)

RandomAccessFile,随机访问文件,自身具备读写的方法。通过skipBytes(int x),seek(int x)来达到随机访问。!!!!!这个是他的优点.

import java.io.*;class IoTextDemo{public static void main(String[] args) throws Exception{//writeFile();//readFile();writeFile_2();}public static void writeFile() throws IOException{RandomAccessFile raf = new RandomAccessFile("E:\\hebing\\ran1.txt","rw");raf.write("王五".getBytes());//一个中文2个字节//raf.write(97);//raf.write只写最低8位,如果超过就不能正确打印比如258,//但是可以用WriteInt();//文件中是王五a,读四个字节//因为记事本回去查GBKraf.writeInt(97);//文件中是王五   a,中间有3个空格!!!(不是空格,应该是换行符,如果是空格,我自己写的三个空格,等会读年龄的时候读不出来)raf.write("赵四".getBytes());raf.writeInt(22);raf.close();}public static void readFile() throws IOException{RandomAccessFile raf = new RandomAccessFile("E:\\hebing\\ran1.txt","r");//之前打印//name=王五//age=97//调整对象中指针   前后都可以//raf.skipBytes(8); //跟下面效果一样,只是只能往前走不能往后走!!!!!raf.seek(8);//相当于从第八个字节开始读  一个中文2个字节,int四个字节//现在打印//name=赵四//age=22byte[] buf =new byte[4];raf.read(buf);String name = new String(buf);int age = raf.readInt();System.out.println("name="+name);System.out.println("age="+age);raf.close();}//可以中间不写,直接写第四个,,或者修改之前写过的,在平常下载的时候,//每一段数据都是单独一个线程进行写,这样就要求数据有规律,比如录入户口,16个字节写名字,四个字节写年龄//20个字节是一个人,所以这样就可以分段读写//如果是一般流,只能从头写到尾,只是多个线程从头写到位,那么数据不是按顺序来的,//解码会报错(如下图)public static void writeFile_2()throws IOException{RandomAccessFile raf = new RandomAccessFile("E:\\hebing\\ran1.txt","rw");raf.seek(8*5);//从第四十个字节开始写raf.write("周期".getBytes());raf.writeInt(103);raf.close();}}

三十八.IO流中的管道流

管道流
PopedinputStream 和PipedOutStream
输入输出可以直接进行连接,通过结合教程使用。
管道输入流应该连接到管道输出流;
管道输入流提供要写入管道输出流的所有数据字节。通常,
数据由某个线程从 PipedInputStream 对象读取,
并由其他线程将其写入到相应的 PipedOutputStream。
不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。

import java.io.*;class IoTextDemo{public static void main(String[] args) throws IOException{PipedInputStream in = new PipedInputStream();PipedOutputStream out = new PipedOutputStream ();in.connect(out);Read r = new Read(in);Write w = new Write(out);new Thread(r).start();new Thread(w).start();}}class Read implements Runnable {private PipedInputStream in;Read(PipedInputStream in){this.in = in;}public void run(){try{System.out.println("读取钱。。。没有数据就阻塞");byte[] buf = new byte[1024];int len = in.read(buf);// //阻塞式方法读取数据(如果没有数据就停在这,这时候其他线程就获取执行权)System.out.println("读到数据,阻塞结束");String s = new String(buf,0,len);System.out.println(s);in.close();}catch (IOException e){throw new RuntimeException("管道读取失败");}//  这种方法虽然OK,但是不适合代码原理展示//PrintStream ps = new PrintStream(System.out);//int line = 0;//try//{//0-255的ASKII值//while((line = in.read()) !=  -1)//{////ps.println((char)line);//}//in.close();//ps.close();//}//catch (IOException e)//{//throw new RuntimeException("管道读取流失败");//}}}class Write implements Runnable{private PipedOutputStream out;Write(PipedOutputStream out){this.out = out;}public void run(){try{System.out.println("开始写入数据,等待6秒");Thread.sleep(6000);out.write("da wang jiao wo lai xun shang".getBytes());out.close();}catch (Exception e){throw new RuntimeException("管道输出流失败");}}}


三十九.IO流操作基本数据类型的流对象DataStream

重点在于:可以用于操作基本数据类型的数据的流对象,把基本数据和流结合起来!!!!

import java.io.*;class IoTextDemo{public static void main(String[] args)throws IOException{//writeData();readData();}public static void writeData()throws IOException{DataOutputStream dos = new DataOutputStream(new FileOutputStream("E:\\hebing\\data.txt"));dos.writeInt(234);dos.writeBoolean(true);dos.writeDouble(9887.543);dos.close();}public static void readData()throws IOException{//必须按照写的顺序读DataInputStream dis = new DataInputStream(new FileInputStream("E:\\hebing\\data.txt"));int num = dis.readInt();boolean b =dis.readBoolean();double d = dis.readDouble();System.out.println("num="+num);System.out.println("b="+b);System.out.println("d="+d);dis.close();}//以与机器无关方式使用 UTF-8 修改版编码将一个字符串写入基础输出流。public static void writeUTFDemo()throws IOException{DataOutputStream dos = new DataOutputStream(new FileOutputStream("E:\\hebing\\data.txt"));dos.writeUTF("你好");//用什么编码写就必须要用什么编码读dos.close();}public static void readUTFDemo()throws IOException{DataInputStream dis = new DataInputStream(new FileInputStream("E:\\hebing\\data.txt"));String s = dis.readUTF();System.out.println(s);dis.close();}}

四十.用于操作字节数组的流对象

ByteArrayInputStream:在构造的时候,需要接受数据源,而且数据源是一个字节数组。
ByteArrayOutputStream :在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数据,这就是数据的目的地(这就是他的重点)
下面这几个原理都是一样的
*************************************************
操作字节数组
ByteArrayInputStream与ByteArrayOutputStream
操作字符数据
CharArrayReader与CharArrayWrite
操作字符串
StringReader与StringWriter
**************************************************
因为这两个流对象都操作的数组,并没有使用系统资源(底层资源)
所以,不用进行close关闭。而且关不关闭,这个流对象都能继续使用
1.源设备,
键盘 System.in , 硬盘 FileStream , 内存ArrayStream  !!!!!!!!!!
2.目的设备:
控制台 System.out   硬盘FileStream, 内存ArrayStream. !!!!!!!!!!


这里的源和目的都是内存
用流的读写思想来操作数据

import java.io.*;class IoTextDemo{public static void main (String[]  args){//数据源ByteArrayInputStream  bis = new ByteArrayInputSream(“ABCDEFG”.getBytes());//都在内存中//数据目的ByteArrayOutputStream bos = new ByteArrayOutputStream();//都在内存中//不用写目的,因为目的被封装在内部,可变的字符数组int by = 0;while((by = bis.read()) != -1){bos.write(by);}System.out.println(bos.size());//7System.out.println(bos.toString()); //ABCDEFG}}

四十一.IO流转换流的字符编码

字符编码
字符流的出现是为了方便操作字符
更重要的是加入了编码转换

原理:!!!!!!
通过子类转换流来完成
InputStreamReader
OutputStreamWriter
在两个对象进行构造的时候加入字符集(也就是编码表)

常见的编码表
ASCII:美国标准信息交换码
用一个字节的7位可以表示

ISO8859-1:拉丁码表。欧洲码表
用一个字节的8位表示(比如打头为1,怎么写都跟前面的都不一样)

GBK2312:中国的中文编码表。(两个字节高位都是1,兼容ASCII码)

GBK:中国的中文编码表升级,融合了更多的中文文字符号

Unicode:国际标准码,融合了多种文字
所有文字都用两个字节来表示,java语言使用的就是unicode

UTF-8:最多用三个字节来表示一个字符

import java.io.*;class IoTextDemo{public static void main(String[] args) throw IOException{readText();}}public static void readText() throws IOException{InputStreamReader isr = InputStreamReader(new FileInputStream(“gbk.txt”),”GBK”);char[] buf = new char[10];int len = isr.read(buf);String str = new String (buf, 0, len);System.out.printlb(str);isr.close();}public static void writeText() throws IOException{OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(“utf.txt”),”UTF-8”);osw,write(“你好”);osw.close();}

四十二.编码解码

编码:字符串变成字节数组
解码:字节数组变成字符串

String -- >byte[] ;str.getBytes(charsetName);
byte  -- > String: new String(byte[],charsetName);

import  java.util.*;class EncideDemo{public static void main(String[] args) throws Exception{String s = “你好”;byte[]  b1 = s.getBytes(“utf-8”); //编码System.out.println(Arrays.toString(b1));  //打印出他的字节String s1 = new String(b1 , “UTF-8”);System.out.println(“s1=”+s1);  //解码}//解码错了,在编回去,就OK了public static void  method_1(){String s = "你好";byte[] b1 = s.getBytes("GBK");System.out.println(Arrays.toString(b1));  //打印出按照GBK编码的每个字节String s1 = new String (b1,"iso8859-1");System.out.println("s1="+s1);//打印解码出的字符byte[] b2 = s1.getBytes("iso8859-1");System.out.println(Arrays.toString(b2)); //按照iso8859编码出的每个字节String s2 = new String(b2,"gbk");System.out.println("s2= "+s2);}!!!!!//解码错了,在编回去,不行了//往回编的时候编错了,因为GBK,UTF-8都识别中文,服务器用的是IOS8859//GBK用两个字节编码中文,UTF-8用三个,这是根本原因,用三个的原因,是因为识别到了使用三个字节的格式//UTF编码原理//utf编码是不定长编码,每一个字符的长度从1-6个字//节不等。另外,utf编码自带简单的校验功能。一般来讲,英文字母都是用一个字节表示,而汉字使用三个字节public static void  method_2(){String s = "你好";byte[] b1 = s.getBytes("GBK");System.out.println(Arrays.toString(b1));  //打印出按照GBK编码的每个字节String s1 = new String (b1,"UTF-8");System.out.println("s1="+s1);//打印解码出的字符byte[] b2 = s1.getBytes("UTF-8");System.out.println(Arrays.toString(b2)); //按照iso8859编码出的每个字节String s2 = new String(b2,"gbk");System.out.println("s2= "+s2);}}

四十三.联通问题

UTF-8是读取三个字节成一个中文,
怎么判断取一个字节,还是去两个字节,还是三个字节
联通这两个字的编码正好符合UTF-8取两个字节的规则,所以乱码,他是三个字节做一个中文


开头 0  读一个字节
字节 1 0 位 6-0


开头110
第二字节10   读两个字节


字节 1 1 1 0 位 10-6


字节 2 1 0 位 5-0




第三个字节
字节 1 1 1 1 0位 15-12


字节 2 1 0 位 11-6


字节 3 1 0 位 5-0

class EncodeDemo2{public static void main(String[] args)throws Exception{String s = "联通";byte[] by = s.getBytes("gbk");for(byte b:by){System.out.println(Integer.toBinaryString(b&255))//打印成二进制//取最后八位}}}

四十四.练习

需求:
有五个学生,每个学生有三门课的成绩
从键盘输入以上数据(包括姓名,三门课成绩),
输入的格式:如:zhangsan , 30 , 40 ,60计算出总成绩,
并把学生的信息和计算出的总分数高低顺序存档在磁盘文件”stud.txt”中


1.描述学生对象
2.定义一个可操作学生对象的工具类。


思想:
1.通过获取键盘录入一行数据,并将该行中的信息取出封装成对象。
2.因为学生有很多,那么就需要存储,使用到集合,因为对学生的总分排序
所以可以使用TreeSet.
3.将集合的信息写入到一个文件中。

import java.io.*;import java.util.*;class IoTextDemo{public static void main(String[] args) throws IOException{TreeSet<Student> stus = StudentInfoTool.getStudents();//默认顺序从小到大,现在从大到小StudentInfoTool.writeToFile(stus);}}class StudentInfoTool{public static TreeSet<Student> getStudents()throws IOException{BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));TreeSet<Student> ts = new TreeSet<Student>();String line = null;while((line = bufr.readLine()) != null){if("over".equals(line)){break;}//把输入的字符按逗号区分开String[] info = line.split(",");//自己写的时候就卡在这个地方(怎么把输入的数据添加到集合中)//parseInt(String s)将字符串参数作为有符号的十进制数进行解析Student stu = new Student(info[0],Integer.parseInt(info[1]),Integer.parseInt(info[2]),Integer.parseInt(info[3]));ts.add(stu);}bufr.close();return ts;}public static void writeToFile(TreeSet<Student> ts1) throws IOException{BufferedWriter bufw = new BufferedWriter(new  FileWriter("E:\\hebing\\Stu_info.txt") );for(Student s:ts1){bufw.write(s.toString()+'\t');bufw.write(s.getSum()+"");bufw.newLine();bufw.flush();}bufw.close();}}//因为要排序,所以选择TreeSet,这里就用排序两种方法之一实现Comparableclass Student implements Comparable<Student>{private String name;private int cn;private int en;private int math;private int sum;Student(String name , int cn , int en , int math){this.name = name;this.cn = cn;this.en = en;this.math = math;this.sum = cn+en+math;}public String getName(){return name;}public int getSum(){return sum;}public int hashCode(){return name.hashCode()+sum*2;}public boolean equals(Student obj){return (this.name.equals(obj.name))&&(this.sum == obj.sum);}//继承comparable需要复写compareTo这个方法public  int compareTo(Student s){//这个地方写错了!!!!!int num = new Integer(this.sum).compareTo(new Integer(s.sum));if(num == 0){return this.name.compareTo(s.name);}return num;}public String toString(){//等会把数据按照这样的格式写入文件中return name+","+en+","+cn+","+math+","+sum;}}






0 0
原创粉丝点击