------- android培训、java培训、期待与您交流!----------
导读:对象的序列化,管道流,RandomAccessFile,操作基本数据类型的流对象, ByteArrayStream,字符流的字符编码,编码解码,字符编码-联通,练习
1、IO流(对象的序列化)
Ø ObjectOutputStream(OutputStream out):创建写入指定 OutputStream 的ObjectOutputStream。(接收一个流进来)
Ø write();
Ø writeInt(int val)等:可以操作基本数据类型。writeInt(int val),可以将四个字节全部写出去。区别于write(int val)方法。
Ø write():只将最低的8位写出去。
Ø void writeObject(Object obj):将指定的对象写入 ObjectOutputStream。(方法可以接收一个对象进来)
class ObjectStreamDemo
{
publicstatic void main(String[] args) throws Exception
{
//writeObj();
readObj();
}
public static void readObj()throws Exception
{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
Personp = (Person)ois.readObject();
System.out.println(p);
ois.close();
}
public static void writeObj()throws IOException
{
ObjectOutputStream oos =
newObjectOutputStream(new FileOutputStream("obj.txt"));
//一般不存成obj.txt,因为txt可以打开,可是打开也看不懂,可以存成person.object
oos.writeObject(newPerson("lisi0",399,"kr")); //这里的kr是不能够被序列化到硬盘上,因为kr传进去之后是静态的,不是在堆内存中的,不被序列化。这里可以写多个oos.writeObject(new Person("",""));存入多个对象,readObject()一次返回一个对象,readObject()第二次,返回第二个对象。
oos.close();
}
}
import java.io.*;
class Person implements Serializable
{
//UID给类定义一个序列化的标识,其实就是了为序列化的方便。在生成obj.txt后,在name前加上一个private的时候就会生成一个新的UID。这个时候就不能和原来的obj.txt文件了,不让你读了。为了还可以读原来的文件,可以在类中自己定义一个UID不让java自动生成。
publicstatic final long serialVersionUID = 42L;//自己定义一相UID新的类,还可以用原来的,序列化的对象。
privateString name;
transientint age; //如果非静态的成员也不想让它序列化的话,可以加上transient,其值在堆内存中存在,而不在文本文件中存在。
staticString country = "cn";
Person(Stringname,int age,String country)
{
this.name= name;
this.age= age;
this.country= country;
}
public String toString()
{
return name+":"+age+":"+country;
}
}
2、IO流(管道流)
管道流(PipedInputStream和PipedOutputStream),输入输出可以直接进行连接,通过结合线程使用。
class Read implements Runnable
{
private PipedInputStream in;
Read(PipedInputStreamin)
{
this.in= in;
}
publicvoid run()
{
try
{
byte[] buf = new byte[1024];
System.out.println("读取前。。没有数据阻塞");
intlen = in.read(buf);
System.out.println("读到数据。。阻塞结束");
Strings= new String(buf,0,len);
System.out.println(s);
in.close();
}
catch(IOException e)
{
throw new RuntimeException("管道读取流失败");
}
}
}
class Write implements Runnable
{
privatePipedOutputStream out;
Write(PipedOutputStreamout)
{
this.out= out;
}
public void run()
{
try
{
System.out.println("开始写入数据,等待6秒后。");
Thread.sleep(6000);
out.write("pipedlai la".getBytes());
out.close();
}
catch(Exception e)
{
throw new RuntimeException("管道输出流失败");
}
}
}
class PipedStreamDemo
{
publicstatic void main(String[] args) throws IOException
{
PipedInputStreamin = new PipedInputStream();
PipedOutputStreamout = new PipedOutputStream();
in.connect(out);
Readr = new Read(in);
Writew = new Write(out);
newThread(r).start();
newThread(w).start();
}
}
3、IO流(RandomAccessFile)
Ø RandomAccessFile(File file, String mode)
Ø RandomAccessFile(String name, String mode)
mode 参数指定用以打开文件的访问模式
通过构造函数可以看出,该类只能操作文件。(设备上只有硬盘,没有别的)。而且操作文件还有模式:只读r,读写rw等。
如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。
如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。
Ø int read(byte[] b)
Ø int readInt():读基本数据类型等。
Ø String readLine():读一行。
Ø void seek(long pos):指向位置。
Ø void write(byte[] b)
Ø void writeInt(int v)
Ø int skipBytes(int n):跳过多少个字节。
class RandomAccessFileDemo
{
public static void main(String[] args) throws IOException
{
//writeFile_2();
//readFile();
//System.out.println(Integer.toBinaryString(258));
}
public static void readFile()throws IOException
{
RandomAccessFile raf = new RandomAccessFile("ran.txt","r");
//调整对象中指针。(前提:要保证数据是有规律的,不然取起来就费劲了,为使数据有规律,可以在存的时候补位)
//raf.seek(8*1); //取第二个人。取第一个人是8*0。seek()是前后都能指,想指哪指哪。
//跳过指定的字节数
raf.skipBytes(8); //跳过可以往下跳,但是不能往回跳。
byte[]buf = new byte[4];
raf.read(buf);
Stringname = new String(buf);
intage = raf.readInt();
System.out.println("name="+name);
System.out.println("age="+age);
raf.close();
}
public static void writeFile_2()throws IOException
{
RandomAccessFileraf = new RandomAccessFile("ran.txt","rw");
//一new对象的话,不另创建文件,而是直接在里面写数据。而输出流一new对象就要覆盖文件。
raf.seek(8*3); //如果这里是8*0的话,对于李四这个位置上的数据修改为周七。
raf.write("周七".getBytes());
//随机的可以往里面读写。第一个位置是,李四。第二个位置是王五。第三个位置不知道是什么,直接在第四个位置里写入周七。
raf.writeInt(103);
raf.close();
}
publicstatic void writeFile()throws IOException
{
RandomAccessFileraf = new RandomAccessFile("ran.txt","rw");
raf.write("李四".getBytes());
raf.writeInt(97);
raf.write("王五".getBytes());
raf.writeInt(99); //直接写基本数据类型。
raf.close();
}
}
4、IO流(操作基本数据类型的流对象)
DataOutputStream(OutputStream out):创建一个新的数据输出流,将数据写入指定基础输出流。
class DataStreamDemo
{
public static void main(String[] args) throws IOException
{
//writeData();
//readData();
//writeUTFDemo();
// OutputStreamWriterosw = new OutputStreamWriter(newFileOutputStream("gbk.txt"),"gbk");
// osw.write("你好"); //这里占了4个字节,UTF-8写入占6个字节,修改版的UTF-8占了8个字节。只能用相对应的方法读出来,而不能用UTF-8读出来
// osw.close();
// readUTFDemo();
}
public static void readUTFDemo()throws IOException
{
DataInputStreamdis = new DataInputStream(new FileInputStream("utf.txt"));
Strings = dis.readUTF(); //只能用这个读出来。
System.out.println(s);
dis.close();
}
public static void writeUTFDemo()throws IOException
{
DataOutputStreamdos = new DataOutputStream(new FileOutputStream("utfdate.txt"));
dos.writeUTF("你好");
dos.close();
}
public static void readData()throws IOException
{
DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
int num = dis.readInt(); //写的时候是先写的整数,读的时候也要先读整数。要是以前的话,要先存入4个字节,再将4个字节转化为字符串,再将字符串强转成一个整数。
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();
}
public static void writeData()throws IOException
{
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeInt(234);
dos.writeBoolean(true);
dos.writeDouble(9887.543);
dos.close();
ObjectOutputStreamoos = null;
oos.writeObject(newO());
}
}
5、IO流(ByteArrayStream)
ByteArrayInputStream与ByteArrayOutputStream,是能直接操作字节数组中字节数据的流对象。
Ø int available():返回可从此输入流读取(或跳过)的剩余字节数。
Ø int read():从此输入流中读取下一个数据字节。
Ø void reset():将缓冲区的位置重置为标记位置。
Ø long skip(long n):从此输入流中跳过 n 个输入字节。
ByteArrayOutputStream(int size):size用于指定大小的缓冲区容量。
对象中封装的就是一个可变长度以字节数组,这个数组就是目的。
byte[] toByteArray():创建一个新分配的 byte 数组。
String toString()
void writeTo(OutputStream out):写到目的中去,这个目的可以是一个字节输出流。
Ø ByteArrayInputStream :在构造的时候,需要接收数据源,。而且数据源是一个字节数组。
Ø ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。这就是数据目的地。
因为这两个流对象都操作的数组,并没有使用系统资源。所以,不用进行close关闭。
源设备,
键盘 System.in,硬盘FileStream,内存 ArrayStream。
目的设备:
控制台 System.out,硬盘FileStream,内存 ArrayStream。
class ByteArrayStream
{
public static void main(String[] args)
{
//数据源。
ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes());
//数据目的
ByteArrayOutputStream bos = new ByteArrayOutputStream();
intby = 0;
while((by=bis.read())!=-1) //不用判断数组大小,更方便了。读操作
{
bos.write(by); //写操作
}
System.out.println(bos.size()); //缓冲区的大小
System.out.println(bos.toString());
// bos.writeTo(newFileOutputStream("a.txt")); //只有这一个方法涉及到异常了。
}
}
Ø 操作字符数组:CharArrayReader与CharArrayWrite
Ø 操作字符串:StringReader 与StringWriter
6、IO流(字符流的字符编码)
Ø 字符流的出现为了方便操作字符。
Ø 更重要是的加入了编码转换。
Ø 通过子类转换流来完成。(下面两个是加入了编码表的流对象,还有两个是PrintStream和PrintWriter,这两个只能去打印不能去读取)
Ø InputStreamReader
Ø OutputStreamWriter
Ø 在两个对象进行构造的时候可以加入字符集。
Ø 计算机只能识别二进制数据,早期由来是电信号。
Ø 为了方便应用计算机,让它可以识别各个国家的文字。
Ø 就将各个国家的文字用数字来表示,并一一对应,形成一张表。
Ø 这就是编码表。
Ø ASCII:美国标准信息交换码。(用一个字节的7位可以表示)
Ø ISO8859-1:拉丁码表。欧洲码表(用一个字节的8位表示)
Ø GB2312:中国的中文编码表。(中国的码表兼容ASCII码表,两个字节的高位都用1来表示,带符号六七千个字)
Ø GBK:中国的中文编码表升级,融合了更多的中文文字符号。(扩容了,两万多,56个民族的文字都加进来就好了。GB18030)
Ø Unicode:国际标准码,融合了多种文字。(所有文字都用两个字节来表示,Java语言(char类型)使用的就是unicode。但一个字节能装下的文字,两个字节比较浪费,)
Ø UTF-8:最多用三个字节来表示一个字符。(一个能装下的用一个字节装,二个字节不够的用三个字节装。在每一个字节的开头都有一个标识头,加了之后,就能很容易的区别出什么样的编码才是UTF-8的编码)
class EncodeStream
{
public static void main(String[] args) throws IOException
{
//writeText();
readText();
}
public static void readText()throws IOException
{
InputStreamReader isr = new InputStreamReader(newFileInputStream("utf.txt"),"gbk");
char[] buf = new char[10];
int len = isr.read(buf);
String str = new String(buf,0,len);
System.out.println(str);
isr.close();
}
publicstatic void writeText()throws IOException
{
OutputStreamWriterosw = new OutputStreamWriter(newFileOutputStream("utf.txt"),"UTF-8");
osw.write("你好");
osw.close();
}
}
7、编码解码
解码:字节数组变成字符串。
byte[] -->String: newString(byte[],charsetName);
class EncodeDemo
{
public static void main(String[] args)throws Exception
{
Strings = "哈哈";
byte[] b1 = s.getBytes("GBK");
System.out.println(Arrays.toString(b1));
Strings1 = new String(b1,"utf-8");
System.out.println("s1="+s1);
//若对s1进行iso8859-1解码再编码,就能正确的读出来输出正确结果,因为iso8859-1不识别中文。
byte[] b2 = s1.getBytes("utf-8"); //如果这里用utf-8,因为UTF-8和GBK都识别中文,在这里编译将???编码的时候会编码错误,解码的时候也更不会正确。
System.out.println(Arrays.toString(b2));
String s2 = new String(b2,"gbk");
System.out.println("s2="+s2);
}
}
08、字符编码-联通
{
public static void main(String[] args) throws Exception
{
Strings = "联通";
byte[] by = s.getBytes("gbk");
for(byteb : by)
{
System.out.println(Integer.toBinaryString(b&255));
}
System.out.println("HelloWorld!");
}
}
11000001
10101010
11001101
10101000
正好符合UTF-8的形式,所以用记事本打开的时候,记事本查的是UTF-8的编码而不是GBK的编码。所以出现了乱码。可在在记事本的前面加上一个汉字,这样就用GBK来解,不用UTF-8来解就正确了。
9、练习
有五个学生,每个学生有3门课的成绩,
从键盘输入以上数据(包括姓名,三门课成绩),
输入的格式:如:zhagnsan,30,40,60计算出总成绩,
并把学生的信息和计算出的总分数高低顺序存放在磁盘文件"stud.txt"中。
1,描述学生对象。
2,定义一个可操作学生对象的工具类。
思想:
1,通过获取键盘录入一行数据,并将该行中的信息取出封装成学生对象。
2,因为学生有很多,那么就需要存储,使用到集合。因为要对学生的总分排序。
所以可以使用TreeSet。
3,将集合的信息写入到一个文件中。
*/
import java.io.*;
import java.util.*;
class Student implements Comparable<Student>
{
private String name;
private int ma,cn,en;
private int sum;
Student(Stringname,int ma,int cn,int en)
{
this.name= name;
this.ma= ma;
this.cn= cn;
this.en= en;
sum= ma + cn + en;
}
public int compareTo(Student s)
{
intnum = new Integer(this.sum).compareTo(new Integer(s.sum));
if(num==0)
returnthis.name.compareTo(s.name);
return num;
}
public String getName()
{
return name;
}
public int getSum()
{
return sum;
}
public int hashCode()
{
return name.hashCode()+sum*78;
}
public boolean equals(Object obj)
{
if(!(objinstanceof Student))
thrownew ClassCastException("类型不匹配");
Students = (Student)obj;
return this.name.equals(s.name) && this.sum==s.sum;
}
publicString toString()
{
return "student["+name+", "+ma+", "+cn+","+en+"]";
}
}
class Student InfoTool
{
//对外提供两个方法,一个是没有比较器的,另一个是有比较器的。没有比较器的和有比较器的代码大致相同。只用传入null即可,在有比较器中做一下判断。
public static Set<Student> getStudents() throws IOException
{
return getStudents(null);
}
public static Set<Student> getStudents(Comparator<Student> cmp)throws IOException
{
BufferedReaderbu fr =
newBufferedReader(new InputStreamReader(System.in));
Stringline = null;
Set<Student>stus = null;
if(cmp==null) //做一下判断。
stus= new TreeSet<Student>();
else
stus= new TreeSet<Student>(cmp);
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
String[]info = line.split(",");
Student stu = new Student(info[0],Integer.parseInt(info[1]),
Integer.parseInt(info[2]),
Integer.parseInt(info[3]));
stus.add(stu); //二叉树在这里已经排了。
}
bufr.close();
return stus;
}
public static void write2File(Set<Student> stus) throws IOException
{
BufferedWriterbu fw = new BufferedWriter(new FileWriter("stuinfo.txt"));
for(Studentstu : stus)
{
bufw.write(stu.toString()+"\t");
bufw.write(stu.getSum()+"");
bufw.newLine();
bufw.flush(); //带缓冲区,一定要flush()
}
bufw.close();
}
}
class StudentInfoTest
{
public static void main(String[] args) throws IOException
{
Comparator<Student> cmp = Collections.reverseOrder();
//定义一个自己的比较器,将成绩反转,按从大到小排列,否则默认的是从小到大。
Set<Student> stus = StudentInfoTool.getStudents(cmp);
StudentInfoTool.write2File(stus);
}
}
/*
猜数字游戏:
1,产生随机数。
2,获取键盘录入。
3,将录入数据变成数字,和随机数比较。
给出提示信息。
4,重复这个过程,如果猜中,程序就结束。
注意:对于输入1~100以外的数字,,以及非数字要给出提示。
*/
import java.io.*;
import java.util.*;
class GuessNumber
{
private int ranNum;
GuessNumber()
{
Randomr = new Random();
ranNum= r.nextInt(100)+1;//(int)Math.random()*100+1;
}
public void play()
{
System.out.println("游戏开始:输入1~100之间的数字:");
boolean b = false;
while(!b)
{
try
{
int num = getNum();
if(num>=1&& num<=100)
b= isLuck(num);
else
System.out.println("数值超出范围");
}
catch(IOException e)
{
throw new RuntimeException("录入数据失败");
}
catch(NumberFormatExceptione)
{
System.out.println("输入了非法数据");
}
}
}
//获取键盘的数字
privateint getNum()throws IOException,NumberFormatException
{
BufferedReaderbu fr = new BufferedReader(new InputStreamReader(System.in));
int num = Integer.parseInt(bufr.readLine());
return num;
}
//和随机数比较
private boolean isLuck(int num)
{
booleanb = false;
if(num>ranNum)
System.out.println("大了,继续");
elseif(num<ranNum)
System.out.println("小了,继续");
else
{
System.out.println("中了,恭喜");
b= true;
}
returnb;
}
}
class GuessNumberDemo
{
public static void main(String[] args)
{
new GuessNumber().play();
}
}
------- android培训、java培训、期待与您交流!----------
文章浏览阅读1.6w次,点赞8次,收藏41次。生活中我们无时不刻不都要在网站搜索资源,但就是缺少一个趁手的资源搜索网站,如果有一个比较好的资源搜索网站可以帮助我们节省一大半时间!今天小编在这里为大家分享5款超厉害的资源搜索网站,每一款都可以让你的资源丰富精彩!网盘传奇一款最有效的网盘资源搜索网站你还在为找网站里面的资源而烦恼找不到什么合适的工具而烦恼吗?这款网站传奇网站汇聚了4853w个资源,并且它每一天都会持续更新资源;..._最全资源搜索引擎
文章浏览阅读4.5k次,点赞5次,收藏18次。阅读测试程序,设计一个Book类。函数接口定义:class Book{}该类有 四个私有属性 分别是 书籍名称、 价格、 作者、 出版年份,以及相应的set 与get方法;该类有一个含有四个参数的构造方法,这四个参数依次是 书籍名称、 价格、 作者、 出版年份 。裁判测试程序样例:import java.util.*;public class Main { public static void main(String[] args) { List <Book>_6-1 book类的设计java
文章浏览阅读613次,点赞28次,收藏27次。相比于以前的传统手工管理方式,智能化的管理方式可以大幅降低学校的运营人员成本,实现了校园导航的标准化、制度化、程序化的管理,有效地防止了校园导航的随意管理,提高了信息的处理速度和精确度,能够及时、准确地查询和修正建筑速看等信息。课题主要采用微信小程序、SpringBoot架构技术,前端以小程序页面呈现给学生,结合后台java语言使页面更加完善,后台使用MySQL数据库进行数据存储。微信小程序主要包括学生信息、校园简介、建筑速看、系统信息等功能,从而实现智能化的管理方式,提高工作效率。
传统上用户登陆状态会以 Session 的形式保存在服务器上,而 Session ID 则保存在前端的 Cookie 中;而使用 JWT 以后,用户的认证信息将会以 Token 的形式保存在前端,服务器不需要保存任何的用户状态,这也就是为什么 JWT 被称为无状态登陆的原因,无状态登陆最大的优势就是完美支持分布式部署,可以使用一个 Token 发送给不同的服务器,而所有的服务器都会返回同样的结果。有状态和无状态最大的区别就是服务端会不会保存客户端的信息。
文章浏览阅读784次。发表于10小时前| 2674次阅读| 来源TechCrunch| 19 条评论| 作者Jon EvansiOSAndroid应用开发产品编程语言JavaObjective-C摘要:即便Android市场份额已经超过80%,对于开发者来说,使用哪一个平台做开发仍然很难选择。本文从开发环境、配置、UX设计、语言、API、网络、分享、碎片化、发布等九个方面把Android和iOS_ios 开发角度
搜索引擎的发展历史可以追溯到20世纪90年代初,随着互联网的快速发展和信息量的急剧增加,人们开始感受到了获取和管理信息的挑战。这些阶段展示了搜索引擎在技术和商业模式上的不断演进,以满足用户对信息获取的不断增长的需求。
文章浏览阅读990次。对象特性是指控制对象的输出参数和输入参数之间的相互作用规律。放大系数K描述控制对象特性的静态特性参数。它的意义是:输出量的变化量和输入量的变化量之比。时间常数T当输入量发生变化后,所引起输出量变化的快慢。(动态参数) ..._控制对象特性
文章浏览阅读5.7w次,点赞50次,收藏276次。FRP搭建内网穿透1.概述:frp可以通过有公网IP的的服务器将内网的主机暴露给互联网,从而实现通过外网能直接访问到内网主机;frp有服务端和客户端,服务端需要装在有公网ip的服务器上,客户端装在内网主机上。2.简单的图解:3.准备工作:1.一个域名(www.test.xyz)2.一台有公网IP的服务器(阿里云、腾讯云等都行)3.一台内网主机4.下载frp,选择适合的版本下载解压如下:我这里服务器端和客户端都放在了/usr/local/frp/目录下4.执行命令# 服务器端给执_locyanfrp
文章浏览阅读687次。题目:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=93745#problem/A题意:给出r*c的01矩阵,可以翻转格子使得0表成1,1变成0,求出最小的步数使得每一行中1的个数相等,每一列中1的个数相等。思路:网络流。容量可以保证每一行和每一列的1的个数相等,费用可以算出最小步数。行向列建边,如果该格子是_uva12534
文章浏览阅读504次。1、Let's Encrypt 90天,支持泛域名2、Buypass:https://www.buypass.com/ssl/resources/go-ssl-technical-specification6个月,单域名3、AlwaysOnSLL:https://alwaysonssl.com/ 1年,单域名 可参考蜗牛(wn789)4、TrustAsia5、Alpha..._csdn alphassl免费申请
文章浏览阅读1.6k次。测试算法的性能 很多时候我们需要对算法的性能进行测试,最简单的方式是看算法在特定的数据集上的执行时间,简单的测试算法性能的函数实现见testSort()。【思想】:用clock_t计算某排序算法所需的时间,(endTime - startTime)/ CLOCKS_PER_SEC来表示执行了多少秒。【关于宏CLOCKS_PER_SEC】:以下摘自百度百科,“CLOCKS_PE_算法性能测试
文章浏览阅读1.2k次。fromhttps://towardsdatascience.com/finding-lane-lines-simple-pipeline-for-lane-detection-d02b62e7572bIdentifying lanes of the road is very common task that human driver performs. This is important ..._lanedetectionlite