您的位置:首页 > 编程语言 > Java开发

Java基础学习记录(三)

2020-03-05 21:27 239 查看

System:
描述系统一些信息。
获取系统属性信息:Properties getProperties

因为Properties是Hashtable子类,也就是Map集合的一个子类对象、
那么可以通过map的方法取出该集合中的元素。
该集合中存储都是字符串。没有泛型定义

Runtime对象
该类并没有提供构造函数
说明不可以new对象。那么会直接想到该类中的方法都是静态的
发现该类中还有非静态方法
说明该类肯定会提供方法获取本类对象。而且该方法是静态的,

由这个特点可以看出该类使用了单例设计模式完成。

该方法是 static Runtime getRuntime();

Date类已逐渐被Calendar类取代
月份需要加一
而星期是从周日算起来

IO(Input Output)流
*IO流用来处理设备之间的数据传输
*Java对数据的操作是通过流的方式
*Java用于操作流的对象都在IO包
*流按照操作数据分为两种:字节流与字符流。
*流按流向分为:输入流,输出流。
IO流常用基类
*字节流的抽象基类
*InputStream,OutputStream
*字符流的抽象基类
*Reader,Writer
*注:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀
*如:InputStream的子类FileInputStream
*如:Reader的子类FileReader

因为是对IO流进行操作,所以也要进行异常处理

读取文件的第一种方式,一个字符一个字符读 read()
创建一个文件读取流对象和指定名称的文件相关联
要保证该文件是已经存在的。如果不存在,会发生异常FileNotFoundException
FileReader fr = new FileReader(“demo.txt”);
调用读取流对象的read方法
Read():一次读一个字符,而且会自动往下读。

读取文件的第二种方式:通过字符数组进行读取
在read中传入一个字符数组,用于存储读到的字符。
该read(char[])返回的是读到字符个数。

缓冲区的出现是为了提高流的操作效率而出现的
所以在创建缓冲区必须要先有流对象

该缓冲区中提供了一个跨平台的换行符
newLine();
创建一个字符写入流对象
FileWriter fw = new FileWriter(“buf.txt”);
为了提高字符写入流效率。加入了缓冲技术。
只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数既可以
BufferedWriter bufw = new BufferedWriter(fw);
用到缓冲区就要记得刷新。
关闭缓冲区,就是在关闭缓冲区中的流对象。

字符读取流缓冲区
该缓冲区提供了一次读一行的方法readLine,方便于对文本数据的获取。
当返回null时,表示读到文件末尾

readLine方法返回的时候只返回回车符之前的数据内容,并不返回回车符。

装饰设计模式:
当想要对已有的对象进行功能增强时,
可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。
那么自定义的该类称为装饰类。

装饰类通常会通过构造方法接收被装饰对象。
并基于被装饰的对象的功能,提供更强的功能。

MyReader//专门用于读取数据的类。
|–MyTextReader
|–MyBufferTextReader
|–MyMediaReader
|–MyBufferMediaReader
|–MyDataReader
|–MyBufferDataReader

class MyBufferReader
{
MyBufferReader(MyTextReader text)
{}
MyBufferReader(MyMediaReader media)
{}
}
上面这个类扩展性很差
找到其参数的共同类型。通过多态的形式可以提高扩展性

class MyBufferReader extends MyReader
{
MyBufferReader(MyReader r)
{}
}

MyReader // 专门用于读取数据的类
|–MyTextReader
|–MyMediaReader
|–MyDataReader
|–MyBufferReader

装饰模式比继承要灵活。避免了继承体系臃肿
而且降低了类与类之间的关系。

装饰类因为是增强已有对象,具备的功能和已有的是相同,只不过提供了更强功能。
所以装饰类和被装饰类通常是都属于一个体系中的。
字符流
FileReader
FileWriter

BufferedReader
BufferedWriter

字节流:
InputStream OutputStream
需求,需要操作图片数据。这时就要用到字节流

复制一个图片
思路:
1.用字节读取流对象和图片关联。
2.用字节写入流对象创建一个图片文件。用于存储获取到的图片数据
3.通过循环读写,完成数据的存储。
4.关闭资源。

最后一定要在finally中关闭资源

读取键盘录入
System.out:对应的是标准输出设备,控制台
System.in: 对应的标准输入设备:键盘

read将byte提升成int型避免-1的发生
write进行了强转保留了最低八位的数据


字符流
FileReader
FileWriter

BufferedReader
BufferedWriter
字节流
FileInputStream
FileOutputStream

BufferedInputStream
BufferedOutputStream

能不能直接使用readLine方法来完成键盘录入的一行数据的读取呢?

readLine方法是字符流BufferedReader类中的方法

而键盘录入的read方法是字节流InputStream的方法

那么能不能将字节流转成字符流再使用字符流缓冲区的readLine方法呢?

OutputStreamWriter:是Writer的子类,将输出的字符流变为字节流,即:将一个字符流的输出对象变为字节流的输出对象。
InputStreamReader:是Reader的子类,将输入的字节流变为字符流,即:将一个字节流的输入对象变为字符流的输入对象。

流操作的基本规律:
流对象有很多,不知道改用哪一个

通过两个明确来完成。
1.明确源和目的。
源:输入流 InputStream Reader
目的:输出流 OutputStream Writer
2.操作的数据是否是纯文本。
是:字符流
不是:字节流
3.当体系明确后,再明确要使用哪个具体的对象。
通过设备来进行区分。
源设备:内存,硬盘,键盘。
目的设备:内存,硬盘,控制台。

1.将一个文件中数据存储到另一个文件中。复制文件
源:因为是源,所以使用读取。InputStream Reader
是不是操作文本文件。
是:这时就可以选择Reader
这样体系就明确了

接下来明确要使用该体系中的哪个对象。
明确设备:硬盘,上一个文件
Reader体系中可以操作文件的对象是FileReader

是否需要提高效率:是!。加入Reader体系中缓冲区BufferedReader

FileReader fr = new  FileReader("a.txt");
BufferedReader bufr = new BufferedReader(fr);

目的:OutputStream  Writer
是否是纯文本。
是!Writer
设备:硬盘,一个文件
Writer体系中可以操作文件的对象FileWriter。
是否需要提高效率:是!。加入Writer体系中缓冲区BufferedWriter

FileWriter fw = new FileWriter("b.txt");
BufferedWriter bufw = new BufferedWriter(fw);

2.需求:将键盘录入的数据保存到一个文件中。
这个需求中有源和目的都存在。
那么分别分析
源:InputStream Reader

是不是纯文本?是!Reader
设备:键盘。对应的对象是System.in。
不是选择Reader吗?System.in对应的不是字节流吗?
为了操作键盘的文本数据方便。转成字符流按照字符串操作是最方便的。
所以既然明确了Reader,那么就将System.in转换成Reader。
用来Reader体系中的转换流,InputStreamReader
InputStreamReader isr = new InputStreamReader(System.in);

需要提高效率吗?需要!BufferedReader
BufferedReader bufr = new BufferedReader(isr);

目的:OutputStream Writer
是否是纯文本?是!Writer。
设备:硬盘。一个文件。使用FileWriter。
FileWriter fw = new FileWriter("c.txt");
需要提高效率吗?需要!
BufferedWriter bufw = new BufferedWriter(fw);
扩展一下,想要把录入的数据按照制定的编码表(UTF-8),将数据存到文件中
目的:OutputStream Writer
是否是纯文本?是!Writer。
设备:硬盘。一个文件。使用FileWriter。
但是FileWriter是使用的默认编码表。GBK

但是存储时,需要加入制定的编码表。而只有转换流可以指定。
所以要使用的对象是OutputStreamWriter。
而该转换流对象要接收一个字节输出流。而且还可以操作的文件的字节输出流。FileOutputStream。

OutputStreamWriter osw =
new OutputStreamWriter(new FileOutputStream("d.txt"),"UTF-8");
需要高效吗?需要。
BufferedWriter bufw = new BufferedWriter(osw);

所以,记住。转换流什么使用,字符和字节之间的桥梁,通常,涉及到字符编码转换时,
需要用到转换流。



列出指定目录下文件或者文件夹,包含子目录中的内容
也就是列出指定目录下所有内容

因为目录中还有目录,只要使用同一个列出目录功能的函数完成即可
在列出过程中出现的还是目录的话,还可以再次调用本功能。
也就是函数自身调用自身
这种表示形式,或者编程手法,称为递归

递归要注意:
1.限定条件

2.要注意递归的次数。尽量避免内存溢出

Properties是hashtable子类
也就是说它具备map集合的特点。而且它里面存储的键值对都是字符串

是集合中和IO技术相结合的集合容器。
该对象的特点:可以用于键值对形式的配置文件。

那么在加载数据时,需要数据有固定格式,键=值

打印流:
该流提供了打印方法,可以将各种数据类型的数据都原样打印。

字节打印流:
PrintStream
构造函数可以接收的参数类型
1.file对象 File
2.字符串路径 String
3.字节输出流 OutputStream

字符打印流
1.file对象 File
2.字符串路径 String
3.字节输出流 OutputStream
4.字符输出流 Writer

流合并,通过向量Vector将要合并的文件加载进去,再创建枚举对象。

自己不写UID,如果修改了类的内容,就读不到了
静态不能被序列化,静态在方法区里 堆可以序列化
非静态成员不想被序列化,加上关键字transient

管道流PipedStream,输出流和输入流相连接,不通过中间介质,分别开辟线程,独立运行,避免的阻塞的情况。

RandomAccesFile
该类不算是IO体系中子类
而是直接继承自Object

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

其实完成读写的原理就是内部封装了字节输入流和输出流。

通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式:只读r,读写rw等

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

DataInputStream 与DataOutputStream

可以操作基本数据类型的数据的流对象

用于操作字节数组的流对象
ByteArrayInputStream:在构造的时候,需要接收数据源。而且数据源是一个字节数组。

ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。
这就是数据目的地。

因为这两个流对象都操作的数组,并没有使用系统资源。
所以,不用进行close关闭。

在流操作规律讲解时:

源设备,
键盘 System in , 硬盘 FileStream ,内存ArrayStream
目的设备:
控制台 System out,硬盘 FileStream, 内存ArrayStream

用流的读写思想来操作数据

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

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

String–>byte[]; str.getBytes(charsetName);

byte[]–>String : new String(byte[],charsetName);

File类
用来将文件或者文件夹封装成对象。
方便对文件与文件夹进行操作。
File对象可以作为参数传递给流的构造函数
了解File类中的常用方法

IO包中的其他类
*RandomAccessFile
|–随机访问文件,自身具备读写的方法
|–通过skipBytes(int x),seek(int x)来达到随机访问
*管道流
|–PipedInputStream和PipedOutputStream
|–输入输出可以直接进行连接,通过结合线程使用
*操作基本数据类型
|–DataInputStream与DataOutputStream
*操作字节数组
|–ByteArrayInputStream与ByteArrayOutputStream
*操纵字符数组
|–CharArrayReader与CharArrayWrite
*操作字符串
|–StringReader与StringWriter

常见的编码表
*ASCII:美国标准信息交换码
*用一个字节的7位可以表示
*ISO8859-1:拉丁码表。欧洲码表
*用一个字节的8位表示。
*GB2312:中国的中文编码表
*GBK:中国的中文编码表升级,融合了更多的中文文字字符号
*Unicode:国标标准码,融合了多种文字
*所有文字都用两个字节来表示,Java语言使用的就是unicode
*UTF-8:最多三个字节来表示一个字符

转换流的编码应用
*可以将字符以指定编码格式存储
*可以对文本数据指定编码格式来解读
*指定编码表的动作由构造函数完成

正则表达式:符合一定规则的表达式
作用:用于专门操作字符串
特点:用一些特定的符号来表示一些代码操作。这样就简化了书写。
所以学习正则表达式,就是在学习一些特殊符号的使用
好处:可以简化对字符串的复杂操作
弊端:符号定义越多,正则越长,阅读性越差。

正则表达式中 \d 要用\d转义\

具体操作功能:
1.匹配:String matches方法。用规则匹配整个字符串,只要有一处不符合规则,就匹配结束返回false,

2.切割:String split();

3.替换:String replace();

  • 点赞
  • 收藏
  • 分享
  • 文章举报
Diguiser 发布了12 篇原创文章 · 获赞 3 · 访问量 96 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: