JAVA学习之路(九)——io操作

二进制

定义:略
Integer.toBinaryString(n); //方法本质是展示n在内存中的二进制存储情况

for(int i=0;i<n;i++){
	//输出0~n之间的所有二进制数
	System.out,println(Integer.toBinaryString(n));
}

ASCII码:
A~Z:65 到 90
a~z:97 到 122

关于容量大小:
1.位
二进制数的一个数字成为一个位,如整数是32位数;
2.字节 Byte
8位,最初用于表示计算机处理的一个字符,称为字节。反之八位数二进制称为一个字节。如整数是4字节,
字节是计算机中用来衡量数量的最常用单位
数量:1024Byte = 1kByte = 1k
1024KByte = 1MByte = 1M
1024MByte = 1GByte = 1G
1024GByte = 1TByte = 1T
1024TByte = 1PByte = 1P
硬盘和U盘的容量:1000K=1M
3.数量表示方式
4.字符:java字符类型16位,支持常用字符范围0~65535,两个字节
5.网络传输速率以bit/s为单位
100M网络是指每秒传送100Mbit数据,相当于11MByte/s左右

十六进制

定义:略
用来缩写二进制,还可以用来输出特殊字符

补码

补码:将一个固定位数的二进制数,分一半作为负数,而设计的一套编码规则,其目的是为了解决“负数编码“”和计算问题
按位取反加一 (最小值除外)

二进制计算

~:取反
&:与计算
	计算时将两个数对齐位置,对应数字进行与运算
|:或计算
>>>:右移位计算
>>:数学右移
<<:左移位计算

JAVA核心API

什么是JDK API

JDK中包含大量的API类库,所谓API(Application Programming Interface,应用程序编程接口)就是一些已经写好、可供直接调用的功能(在java语言中,这些功能以类的形式封装)
JDK API包含的类库功能强大,经常使用的有:字符串操作,集合操作,文件操作,输入输出操作,网络操作,多线程等等。

JDK包结构

为了便于使用和维护,JDK类库按照包结构划分,不同功能的类划分在不同的包中
经常使用的包如下图所示
在这里插入图片描述
文档注释规范
/**开头 */结尾

String

String是不可变对象
java.long.String 使用了final修饰,不能被继承
字符底层封装了字符数组及针对字符数组的操作方法
字符一旦创建,对象永远无法改变,但字符串引用可以重新赋值
自妇产才内存采用Unicode编码方式,任何一个字符对应两个字节的定长编码

String常量池
java为了提高性能,静态字符串(字面量,常量,常量连接的结果)在常量池中创建,并尽量使用一个对象,重用静态字符串
对于重复出现的字符串直接量,JVM会首先在常量池中查找,如果存在即返回该对象

1.String str = “abc”;
等价于
char[] chs = {‘a’,‘b’,‘c’};
String s = new String(chs);
2.String类型中封装了char数组
3.String对象一旦创建以后无法改变了
4.String常量池优化现象
String为了优化性能,将一样的字符串,“字面量”和常量进行优化,替换为为同一个字符串对象,动态创建的字符串对象不进行优化
字面量也叫直接量,就是使用“”声明字符串
String str = “abc”; //abc为字符串直接量
String s1 = “abc”; //s1和str引用的是同一个对象
String s2 = new String(“abc”); //动态创建的字符串对象,与s1不是同一个变量
String s3 = “a” + “bc”; //字面量连接结果,参与字符串常量池优化,复用为相同的字符串
String s4 = “a”;
String s5 = s4 + “bc”; //字符串变量的连接是动态字符串,不参与优化,不会复用

String API方法
1.String提供了length()方法得到字符个数
2.String每个字符都有唯一序号,String提供一个方法charAt(序号)根据序号获取对应位置的字符
char c = str.charAt(1);
3.查找字符串位置
String str = “java”;
int n =str.indexOf(“a”); //1,没有找到返回-1
n = str.indexOf(“a”,4);//3重载的indexOf可以从指定位置开始查找
n = str.lastIndexOf(“a”);//3,从后向前找

使用substring获取子串

substring方法用于返回一个字符串的子串
在这里插入图片描述
封装一个方法,在方法将输入的URL中的服务器主机名称截取处理,并且返回
如:http://doc.trdu.cn/index.html

public static String parseHost(String url){
	int index = url.indexOf("/",7);
	String host = url.substring(7,index);
	return host;
}

trim

返回字符串的副本,忽略前导空白和尾部空白
空白是指:编码小于等于0x0020的不可见字符

String str = " \n \r \t Tom and Jerry \t \t";
String s = str.trim();
Syatem.out.println(s);  //结果是Tom and Jerry

str = " \n \r \t Tom and Jerry \t \t";
str.trim();    //str.trim()得到的是字符串得副本,不改变原字符串。没有字符串接收则直接被丢弃
Syatem.out.println(str);  //结果是\n \r \t Tom and Jerry \t \t所显示的字符串,

trim非常常用,用来解决意外输入的空格问题

startsWith()和endsWith()

检测一个字符串是否以指定字符串开头或结尾
检查案例文件是否以.png结尾

String file = "logo.png";
boolean b = file.endWith(".png");
System.out.println(b);//true
file = "logo.doc";
b = file.endWith(".png");
System.out.println(b);//false

大小写变换

转换字符串中中英文的大小写形式
常用于解决忽略大小写比较问题
toUpperCase();
toLowerCase();

String str = "我喜欢java";
str = str.toUpperCase();
System.out.println(str);//我喜欢JAVA
str = str.toLowerCase();
System.out.println(str);//我喜欢java
//假设一个文件是否为图片文件
String file = "demo.PNG";
boolean b = file.toLowerCase().endsWith(".png");
System.out.println(b);

StringBulider

1.StringBulider提供的API方法,与String很像
2.区别在于StringBulider可以改变其内部的char数组的内容
3.创建对象后出事容量有16个字符,当数组容量不足时会自动扩容,扩容规则为一倍+2
4.StringBulider方法返回值往往是对象自身,这样StringBulider的方法非常适合函数式编程,也就是函数接着函数连续调用

StringBulider buf = new StringBulider();
buf,append("范");
buf.append("传奇");
syso(buf);

在这里插入图片描述
StringBulider对象的用途
1.String对象连接时,底层采用StringBulider实现的

String s1 = "abc";
String s2 = "def";
String s3 = s1 + s2 + "test";
//其执行原理:
//s3 = new StringBulider(s1).append(s2).append(text).toString();

2.String频繁连接会生成大量的StringBulider对象,直接影响软件性能,建议直接采用一个StringBulider对象解决字符串频繁连接的性能问题

//比较两种方法用时多少
public static void test1(){
	long t1 = System.currentTimeMillis();
	StringBulider buf = new SreingBulider();
	for (int i=0;i<50000;i++){
		bud.append("A");
	}
	long t2 = Syatem.currentTimeMillis();
	Syatem.out,println(t2-t1);
}
public static void test2(){
	long t1 = System.currentTimeMillis();
	String str = "";
	for (int i=0;i<50000;i++){
		str = str + "A";
	}
	long t2 = Syatem.currentTimeMillis();
	Syatem.out,println(t2-t1);
}

3.StringBulider 线程不安全,性能好
StringBuffer 线程安全,性能稍慢

基本正则表达式

什么是正则
1.正则表达式本身就是一个字符串
2.正则表达式用于定义字符串规则
3.正则表达式湖北所有编程语言接受,用于定义检验字符串规则
4.编程语言都提供了API实现字符串规则检查

正则表达式语法

正则表达式 HelloWord
“HelloWorld”
如上规定了十个顺序字符

String reg = "HelloWorld";
String text = "helloWorld";
boolean b = text.matches(reg);
syso(b);

字符集

用于约定一个位置上的字符范围
语法:
[0123456789]表示一个位置上的字符范围是 0123456789 之中的某个字符
例子:
[0123456789]A 可以匹配 0A 1A 2A 3A 4A… 也可以写成[0~9]
匪兵[甲乙丙丁] 可以匹配 匪兵甲 匪兵乙 …
在这里插入图片描述
预定义字符集:
在这里插入图片描述

	//正则是 \dtest 由于java字符串中\必须写成\\
	String regex = "\\dtest";
	String test = "1test";
	boolean b = test.matches(regex);
	System.out.println(b);

java中 ’ \ ’ 写为 ’ \ \ ’ 意思相同

特殊字符

特殊正则表达式字符,需要利用转义字符匹配

	//匹配  .png   要写成\.png
	//java中 \ 要写成 \\
	regex = "\\.png";  
	text = "Xpng";
	b = text.matches(regex);
	syso(b);  //false
	regex = ".png";  
	text = "Xpng";
	b = text.matches(regex);
	syso(b);  //true

在这里插入图片描述
(上面JAVA左右中括号写反)
检查一个字符串是否符合邮政编码(六个数字)规则

String regex = "\\d\\d\\d\\d\\d\\d";
String zip = "100101";
boolean b = zip.mathes(regex);
syso(b);

数量词

约束一个字符出现的次数
在这里插入图片描述
上面案例可以表示为

String regex = "\\d{6}";
String zip = "100101";
boolean b = zip.mathes(regex);
syso(b);

简单电话号码规则

String regex = "\\+86\\s?\\d{11}";
String t1 = "+8618635294657";
String t2 = "+86 18635294657";
String t3 = "+86    18635294657";
syso(t1.matches(regex));
syso(t2.matches(regex));
syso(t3.matches(regex)); //false   

分组

1.将一组正则规则作为一个整体看待
2.分组中可以使用|实现或的关系
手机号:
(\+86)?\d{11}

String regex = "(\\+86)?\\d{11}";
String t1 = "+8618635294657";
String t2 = "18635294657";
syso(t1.matches(regex)); //true
syso(t2.matches(regex)); //true

(\+86|0086)?\d{11}

边界匹配

在这里插入图片描述

//matches方法就是按照从头到尾的规则检查字符串是否符合正则表达式,
//所以是否添加^$在这里没有区别
//如果希望部分查找结果,使用Pattern API
	String regex1 = "\\w{8,10}";
	String regex2 = "^\\w{8,10}$";
	String t1 = "Jyhdghg23";
	String t2 = "Jyhdghg234656";
	System.out.println(t1.matches(regex1)); //true
	System.out.println(t2.matches(regex1)); //false
	System.out.println(t1.matches(regex2)); //true
	System.out.println(t2.matches(regex2)); //false 
	String regex = "\\w{8,10}";
	String test = "HelloWorld_Hello";
	//创建Pattern对象
	Pattern p = Pattern.compile(regex);
	//匹配目标字符串内容
	Matcher m = p.matcher(test);
	//调用Matcher的方法检查匹配结果
	boolean found = m.find();
	System.out.println(found);  //true    ^\\w{8,10}$则为false
	//读取找到的结果
	if(found){
		String str = m.group();
		System.out.println(str);   //输出HelloWorld
	}

split方法(常用)

String的split方法可以将字符串按照特定的分隔符拆分成字符串数组
String[] split(String regex); //参数regex为正则表达式,以regex所表示的字符串为分隔符,将字符串分成字符串数组

String str = "1, Tom,  18659326562,   tom@tedu.cn";
		String[] data = str.split(",\\s*");
		for(int i=0;i<data.length;i++){
			System.out.println(data[i]);
		}

replaceAll

String提供了用于字符串替换的方法
String replaceAll(String regex,String replacement); //将字符串中匹配正则表达式regex的字符串替换成replacement
替换字符串中出现的敏感信息

String str = "他说:我草";
		String s = str.replaceAll("我[去草]", "**");
		System.out.println(s);

Object

Object是所有引用类型的超类,而八个基本类型不具有面向对象特性,不能利用面向对象的特性进行开发
可以把基本类型变成引用类型,使得基本类型可以以引用类型的形式创建出来

public class IntegerDemo1 {

	public static void main(String[] args) {
		doSome("hello");
		Integer i = new Integer(1);
		doSome(1);
	}
	
	public static void doSome(Object arg) {
		//System.out.println(arg);
	}
}

class Integer {
	private int d;
	public Integer(int d) {
		this.d = d;
	}
}

toString方法

Object类中的重要方法,用于返回对象值得字符串表示
原则上建议重写,格式大多遵循“”“类的名字[域值]”
println方法会自动调用toString方法输出对象的信息
1.Object类上定义了toString方法,用于返回对象的文本信息
2.其默认值是:类全名@散列值 (没啥用)
3.Java建议在子类重写此方法,一般都输出对象的属性信息
可以利用开发工具提供的快捷工具实现
4.很多的javaAPI,如println,print方法都会调用toString,可以大大简化代码
字符串连接的时候也会自动调用toString
System.out.println(类名);

equals方法

1.用于比较两个对象是否相等,也就是对象的关键属性是否一致
2.= = 用于比较两个变量是否相等,当比较引用量的时候,就比较引用中保存的地址值是否相等,不能用于比较引用的对象属性是否相等
3.java在Object定义了equals方法,用于比较讲个对象是否相等,但是其默认实现就是利用“==”比较了讲个对象的引用是否一样,默认规则不好,建议使用者合理重写equals方法
4.比较两个字符串是否相等用String重写的equals方法

包装类

包装类是为了解决基本类型不能直接参与面向对象开发的问题,使得基本类型可以以引用类型的方式创建出来
基本类型只有转换为引用类型(包装类),才能以Object形式传入dosome方法

包装类与基本类型的转换:建议采用静态valueOf转换

Double d1 = Double.valueOf(1.0);
Double d2 = Double.valueOf(1.0);
syso(d1 == d2);   //false
//将double包装类转换为基本类型double
double d = d1.doubleValue();
syso(d);     //1.0
//也可以转换为其他数字的基本类型,注意丢失精度的情况
int i = d1.intValue();
syso(i);      //1

数字类型的包装类都有两个常量:MAX_VALUE和MIN_VALUE,可以获取其对应的基本类型的取值范围

将字符串解析为整数
需要注意这些包装类的解析有一个要求,就是字符串保存的值必须是转换的基本类型可以保存的值,否则会抛出NumberFormatException异常

	String line = "123",
	//将字符串解析为整数
	int d = Integer.parseInt(line);
	syso(s);
	double dou = Double.parseDouble(line);
	syso(dou);

JDK5推出了一个特性:自动拆装箱
该特性是编译器认可,而不是虚拟机,编译期在编译时会自动将基本类型与包装类之间转换,这使得我们在编写源代码时可以直接在基本类型与包装类见相互赋值
实际上:

//将基本类型赋给引用类型时会触发编译器的自动装箱特性
	Integer i = 123;
	//触发自动装箱特性,代码在编译期间会改为:
	//Integer i = Integer.valueOf(123);
	int d = i.valueOf(i);

文件

java.io.File
File类的每一个实例用于表示文件系统中的一个文件
使用File我们可以:
1.访问其表示的文件或目录的属性
2.创建或删除文件、目录
3.访问一个目录的所有子项
4.但是不能访问数据

访问当前项目目录下的demo.txt

public static void main(String[] args) {
		//绝对路径
		//File file = new File("D:/其他软件/eclipse/workspace/HelloWorld/src/file");
		//相对路径
		File file = new File("./demo.txt");
		String name = file.getName();
		System.out.println("文件名:"+name);
		
		long length = file.length();
		System.out.println("大小:"+length+"B");
	}

"./"为当前目录,当前目录在不同运行环境下指定的实际路径不同,在eclipse下运行时,当前目录指的就是当前程序所在项目的目录,相对路径有更好的跨平台性,应当使用这种方式

文件操作-File

File:实现对文件的操作
通过File对象可以实现对文件/目录的以下操作:
1.创建,删除文件/目录
2. 获取文件/目录的属性信息
3. 获取指定目录下的所有子项目

构造方法:
1.File(String path)
2.File(File parent,String child)
3.File(String parent,String child)

方法:
1.创建文件
creatNewFile()
2. 创建目录
mkdir():创建一个目录
mkdirs():创建多级目录

思考:如何在当前项目下创建 t/x/a.txt
先创建目录,在目录下再创建文件
3. delete():
删除文件/目录,注意,若删除的目录下还有子文件/目录,删除失败
4. getName():String
获取文件名称
5. length():long
获取文件内容的大小(字节)
对文件进行读写操作的基本单位是字节
6. exists():boolean
判断文件是否存在
通常和其他方法一起使用
eg:创建文件
如果不存在,创建
否则不创建,给出提示
7. isFile():boolean
判断File对象指向的是否是文件
8. isDirectory():boolean
判断File对象指向的是否是目录

public static void main(String[] args) {

		File dir = new File("./a/b/c/d/e/f");
		if(!dir.exists()) {
			dir.mkdirs();
			System.out.println("目录已创建");
		}else{
			System.out.println("目录已存在");
		}
	}

对文件操作:

1.获取某个目录下所有的子项目
listFiles():File[]
思考:若想获取当前项目下所有以.开头的文件,如何实现? --过滤当前项目下所有的内容
listFiles(FileFilter filter):File[]
获取指定目录下所有满足条件的File对象
FileFilter:是个接口,其中有抽象方法accept,此方法用于实现过滤,将过滤条件写在本方法体中。

案例:删除当前项目下a目录(多级目录)
思路:
1.创建File对象表示当前a目录
2.判断是否是目录
是,获取其子项目并遍历,将遍历到的文件/目录删除
不是,直接删除文件即可
代码的过程:
//定义一个方法用于删除给定的文件/目录
deleteFile(File){
if(是目录){
//获取其子项目
//遍历子项目
对遍历到的子项目调用本方法删除
}
//是文件
file.delete();
}

public static void main(String[] args) {
		// TODO Auto-generated method stub
		File dir = new File("./a");
		delete(dir);
	}
	
	private static void delete(File file) {
		if(file.isDirectory()) {
			//先清空目录
			File[] subs = file.listFiles();
			for(int i=0;i<subs.length;i++) {
				File sub = subs[i];
				delete(sub);
			}
		}
		file.delete();
	}

递归:

在一个方法体内部调用方法本身

求阶乘

注意点:递归在实际开发中能避免使用尽量避免,因为资源开销大,运行速度慢

/**
 * 利用文件过滤器获取符合要求的子项
 * */
public static void main(String[] args) {
		// TODO Auto-generated method stub
		File dir = new File(".");
		//MyFilter filter = new MyFilter();
		//匿名内部类
		FileFilter filter = new FileFilter() {
			public boolean accept(File file) {
				String name = file.getName();
				return name.startsWith(".");
			}
		};
		File[] subs = dir.listFiles(filter);
		System.out.println(subs.length);
		for(int i=0;i<subs.length;i++) {
			System.out.println(subs[i].getName());
		}
	}

文件操作 - RandomAccessFile

File的实例可以对文件进行以上3种访问操作,但是不可以访问文件中的数据。

RandomAccessFile实例可以实现对文件数据的访问(读写操作)
构造方法:
RandomAccessFile(File/String dest,String mode)
mode:访问模式
常用的2个访问模式:
“r” :只读 ;“rw”:读写

方法:

  • 写数据:
    write(int n):向文件中写入一个字节

  • 作为了解:
    - 计算机底层存储的是二进制数据,即保存的是0和1,一个二进制数占用的内存大小即为1位,一个字节占用8位
    byte 1字节 8位的
    int 4字节 32位
    long 8字节 64位
    处理器:32位的:处理一个数据时一次占用32位
    byte占用低8位

  • 读数据
    read():int
    读取一个字节数据,以int形式返回,返回的int值只有低八位有数据
    若读取到文件末尾,返回-1
    若原本就是-1,则读出255

public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		RandomAccessFile raf = new RandomAccessFile("./raf.dat","r");
		int d = raf.read();
		System.out.println(d);
		
		d = raf.read();
		System.out.println(d);
		
		raf.close();
	}

按照单字节方式复制效率低,为了提高效率,我们可以采取每次复制一个字节数组的字节量,从而减少复制的次数,提高效率

按照字节数组进行读写数据
按照字节数组读取数据
read(byte[] bys):int
将从文件中读取到的字节数据存入此数组中,int表示实际读取到的字节长度
write(byte[]):向文件中写入一个字节数组
write(byte[] bys,int index,int len)向目标文件中写入bys中从index开始的连续len个字节

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值