Java高级程序设计笔记
一、IO
1.1、IO
i:input输入(读取)
o:output输出(写入)
流:数据(字符,字节)1个字符=2个字节1个字节=8个二进制位
输入:把硬盘中的数据,读取到内存中使用
输出:把内存中的数据,写入到硬盘中保存
1.2、写入数据的原理(内存–>硬盘)
java程序–>VM(java虚拟机)–>OS(操作系统)–>OS调用写数据的方法–>把数据写入到文件中
1.3、字节流
1.3.1、FiLeoutputstream:文件字节输出流
作用:把内存中的数据写入到硬盘的文件之中
构造方法:
FileoutputStream(String name)
创建一个向具有指定名称的文件中写入数据的输出文件流。
FileoutputStream(File file)
创建一个向指定FiLe对象表示的文件中写入数据的文件输出流
参数
string name:目的地是一个文件的路径
File file:目的地是一个文件
构造方法的作用:
1.创建一个FileoutputStream对象
2.会根据构造方法中传递的文件/文件路径,创建一个空的文件
3.会把FiLeoutputStream对象指向创建好的文件
1.3.2、字节输出流的使用步骤(重点)
1.创建一个FileoutputStream对象,构造方法中传递写入数据的目的地
2.调用FiLeoutputstream对象中的方法write,把数据写入到文件中
3.释放资源
1.3.3、public void write(byte[ ] b)
public void write(byte[ ] b)
将 b.Length字节从指定的字节数组写入此输出流。 一次写多个字节
如果写的第一个字节是正数(0-127),那么显示的时候会查询ASCII表
如果写的第一个字节是负数,那第一个字节会和第二个字节,两个字节组成一个中文显示,查询系统默认码表(GBK)
1.3.4、追加内容(续写)
FileOutputStream(String name,boolean append)
创建一个向具有指定name的文件中写入数据的输出文件流。</font>
FiLeOutputStream(File file,boolean append)
创建一个向指定File对象表示的文件中写入数据的文件输出流。
参数:
String name ,FiLe file:写入数据的目的地
booLean append :追加写开关
true:创建对象不会覆盖源文件,继续在文件的末尾追加写数据
false:创建一个新文件,覆盖源文件
换行:写换行符号
windowvs : /r /n
linux : /n
mac: /r
1.3.5、inputStream类&Fil
- java.io.Inputstream:字节输入流
此抽象类是表示字节输入流的所有类的超类。 - 方法
int read() 从输入流中读取数据的下一个字节
int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。
void close()关闭此输入流并释放与该流关联的所有系统资源。
- java.io.FileInputstream extends Inputstream
FileInputstream:文件字节输入流
作用:把硬盘文件中的数据,读取到内存中使用
构造方法:
FiLeInputstream( String name )
FiLeInputstream( File file)
参数:
读取文件的数据源
string name:文件的路径FiLe fiLe:文件
构造方法的作用:
1.会创建一个FileInputStream对象
2.会把FileInputstream对象指定构造方法中要读取的文件
1.3.6、字节输入流读取字节数据
- 字节输入流的使用步骤(重点)∶
1.创建FiLeInputStream对象,构造方法中绑定要读取的数据源
2.使用FileInputStream对象中的方法read,读取文件
3.释放资源
//创建FiLeInputStream对象,构造方法中绑定要读取的数据源
FileInputStream fis = new FileInputStneam("c\\a.txt".);
//使用FiLeInputStream对象中的方法read,读取文件
//int read()读取文件中的一个字节并返回,读取到文件的末尾返回-1
int len = fis.read();
system.out.print1n(len);
//3.释放资源
fis.close(
---------------------------------------------
int read()使用which 循环读取
int len = e; //记录读取到的字节
while( ( len = fis.read() )!=-1){
system.out.print( ( char)len) ;
}
- 读取多个字符
byte[] bytes = new byte[2];
int len = fis.read(bytes);system.out.println(len);//【65、66】
string类的构造方法
String( byte[]bytes):把字节数组转换为字符串
String(byte[ ] bytes,int offset,int length)把字节数组的一部分转换为字符串 offset:数组的开始索引Length :转换的字节个数
system.out.print1n(new string(bytes));//【AB】
1.3.7、文件的复制
文件复制的步骤:
1.创建一个字节输入流对象,构造方法中绑定要读取的数据源
2.创建一个字节输出流对象,构造方法中绑定要写入的目的地
3.使用字节输入流对象中的方法read读取文件
4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
5.释放资源
public class Demoe1copyFile i
public static void main(String[ ] args) throws IOException {
//1.创建一个字节输入流对象,构造方法中绑定要读取的数据源
FileInputstream fis - new FileInputstream( name:" c : \\a.jpg");
//2.创建一个字节输出流对象,构造方法中绑定要写入的目的地
Fileoutputstream fos - new Fileoutputstream( name: "d: \\b.jpg");
1.一次读取一个字节写入一个字节的方式
//3.使用字节输入流对象中的方法read读取文件int len = e;
while(( len = fis.read() )!=-1){
//4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
fos.write( len) ;
}
2.使用数组缓冲读取多个字节,写入多个字节
byte[] bytes = new byte[ 1024];
//3.使用字节输入流对象中的方法read读取文件
int len = 0;
//每次读取的有效字节个数
while(( len = fis.read(bytes) )!=-1){
//4.使用字节输出流中的方法vrite,把读取到的字节写入到目的地的文件中
fos.write(bytes, off: e,len);
)
//5.释放资源(先关写的,后关闭读的;如果写完了,肯定读取完毕了)
fos.close( );
fis.close( );
1.3.8、使用字节流读取中文的问题
使用字节流读取中文文件
1个中文
GBK:占用两个字节
UTF-8:占用3个字节
可以使用字符流
1.4、字符流
java.io.Reader:字符输入流,是字符输入流的最项层的父类,定义了一些共性的成员方法,是一个抽象类
1.4.1、成员方法
- int read()读取单个字符并返回。
- int read(char[] cbuf)一次读取多个字符,将字符读入数组。
- void close()关闭该流并释放与之关联的所有资源。
1.4.2、FileReader
java.io.FiLeReader extends InputstreamReader extends ReaderFileReader:文件字符输入流
作用:把硬盘文件中的数据以字符的方式读取到内存中
构造方法:
FiLeReader( string fiLeName)
FileReader( File file)
参数:读取文件的数据源
String fiLeName :文件的路径
File file:一个文件
FiLeReader构造方法的作用:
1.创建一个FileReader对象
2.会把FileReader对象指向要读取的文件
1.4.3、字符输入流使用步骤
1.创建FiLeReader对象,构造方法中绑定要读取的数据源
2.使用FiLeReader对象中的方法read读取文件
3.释放资源
public static void main(String[] args) throws IOException {
//1.创建FiLeReader对象,构造方法中绑定要读取的数据源
FileReader fr = new FileReader("TEST.txt");
//2.使用FileReader对象中的方法read读取文件
// int read()读取单个字符并返回。
int len = 0;
while(( len = fr.read() )!=-1){
System.out.print( (char)len) ;
}
//int read(char[ ] cbuf)一次读取多个字符,将字符读入数组。
char[] cs = new char[ 1024];//存储读取到的多个字符
int len = e;//记录的是每次读取的有效字符个数
while(( len = fr.read(cs ) )!=-1){
/*
string类的构造方法
string( char[] value)把字符数组转换为字符串
String(char[ ] value,int offset,int count)把字符数组的一部分转换为字符串 offset数组的开始索引count转换的个数
*/
System.out.println(new string(cs,o,len) ) ;
//3.释放资源
fr .close();
1.4.4、FileWriter
java.io.FiLewriter extends outputStreamlwriter extends writer
FiLe writer:文件字符输出流
作用:把内存中字符数据写入到文件中
构造方法:
FiLewriter(File file)根据给定的File 对象构造一个FiLewriter对象。
FiLewriter(String fileName)根据给定的文件名构造一个 Filewriter对象。
参数:写入数据的目的地
String fiLeName :文件的路径
File file:是—个文件
构造方法的作用:
1.会创建一个FiLelriter对象
2.会根据构造方法中传递的文件/文件的路径,创建文件3.会把FiLelwriter对象指向创建好的文件
1.4.6、字符输出流使用步骤
字符输出流的使用步骤(重点)∶
1 .创建FiLelriter对象,构造方法中绑定要写入数据的目的地
2.使用Filelriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)
3.使用FiLevriter中的方法fLush,把内存缓冲区中的数据,刷新到文件中
4.释放资源(会先把内存缓冲区中的数据刷新到文件中)
public static void main(string[ ] args) throws IOException {
//1.创建FiLewriter对象,构造方法中绑定要写入数据的目的地
Filewriter fw = new Filewriter("test.txt");
//2.使用FiLewriter中的方法write ,把数据写入到内存缓冲区中(字符转换为字节的过程
// void write(int c)写入单个字符。
fw.write( c: 97);
//3.使用FiLewriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
fiw.flush();
//4.释放资源(会先把内存缓冲区中的数据刷新到文件中)
fw.close();
1.4.7、flush()与close()
- flush :刷新缓冲区,流对象可以继续使用。
- close:先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
public static void main(string[ ] args) throws IOException {
//1.创建FiLewriter对象,构造方法中绑定要写入数据的目的地
Filewriter fw = new Filewriter("test.txt");
//2.使用FiLewriter中的方法write ,把数据写入到内存缓冲区中(字符转换为字节的过程
// void write(int c)写入单个字符。
fw.write( c: 97);
//3.使用FiLewriter中的方法flush,把内存缓冲区中的数据,刷新到文件中
fiw.flush();
fw.write( c: 98);//结果ab
//4.释放资源(会先把内存缓冲区中的数据刷新到文件中)
fw.close();
fw.write( c: 98);//Error
1.4.8、写出其他数据
-
void write(char[ ] cbuf) 写入字符数组。
-
abstract void write(char[ ] cbuf, int off, int len)写入字符数组的某一部分, off数组的开始索引 l.en写的字符个数
-
void write( String str)写入字符串
-
void write(String str, int off, int len)写入字符串的某一部分,
off字符串的开始索引,Len写的字符个数。
1.4.9、续写与换行
续写,追加写:使用两个参数的构造方法
FiLewriter( string fiLeName, boolean append)
FiLewriter(File file, boolean append)
参数:
String fileName , File file:写入数据的目的地
boolean append :续写开关 true:不会创建新的文件覆盖源文件,可以续写;false:创建新的文件覆盖源文件
换行:换行符号
windows : \r\n
linux : / n
mac : /r
1.5、IO异常处理
建议使用try. …catch. . .finally 代码处理异常
(JDK7.0以前)
public static void main(string[] args) {
//提高变量file的作用域,让finally可以使用
//变量在定义的时候,可以没有值,但是使用的时候必须有值
//fw = new FiLewriter("test.txt" , true);执行失败, fw没有值, fw.cLose会报错
Filelriter fw = null;
try{
//可能会产出异常的代码
fw = new Fileriter( "test.txt " ,true);
for ( int i = 0; i <10 ; i++) {
fw.write("Helloworld"+i+"\r\n");
}
}catch( IOException e){
//异常的处理逻辑
system.out.println(e) ;
}finally {
//一定会指定的代码
//创建对象失败了,fw的国f认值就是nuLl, nuLl是不能调用方法的,会抛出NuLLPointerException ,需要增加一个判断,不是nuLL在把资源释放
if(fw!=null){
try{
//fw.close方法声明抛出了IOException异常对象,所以我们就的处理这个异常对象,要么throws ,要么try catch
fw.close();
}catch ( IOException e) {
e.printstackTrace();
}
}
}
(JDK7.0以后)在try中直接设置输入输出流的对象
public static void main(string[]args) {
try(
//1.创建一个字节输入流对象,构造方法中绑定要读取的数据源
FileInputstream fis = new FileInputStream( "c: \\1.jpg");
//2.创建一个字节输出流对象,构造方法中绑定要写入的目的地
Fileoutputstream fos = new FileOutputstream("d: \\1.jpg");)
{
//可能会产出异常的代码
//一次读取一个字节写入一个字节的方式
//3.使用字节输入流对象中的方法read读取文件
int len = e;
while( ( len = fis.read())!=-1){
//4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
fos.write(len);
}catch_(IOException e){
//异常的处理逻辑
system.out.println(e);
}
(JDK9.0)新特性
格式:
A a = new A( );
B b = new B();
try(a , b){
可能会产出异常的代码}
catch(异常类变量变量名){
异常的处理逻辑
}
public static void main(String[] args) throws IOException {
//1.创建一个字节输入流对象,构造方法中绑定要读取的数据源
FileInputstream fis - new FileInputstream( name:"c : \\1.jpg");
//2.创建一个字节输出流对象,构造方法中绑定要写入的目的地
Fileoutputstream fos = new Fileoutputstream( name: "d: \\1.jpg");
try(fis;fos){
//一次读取一个字节写入一个字节的方式
//3.使用字节输入流对象中的方法read读取文件int len = 0;
while(( len = fis.read() )!=-1){
//4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中
fos.write( len) ;
}catch ( IOException e){
system.out.println(e) ;)
}
二、多线程
2.1、并发与并行
并发∶指两个或多个事件在同一个时间段内发生。
并行∶指两个或多个事件在同一时刻发生(同时发生)。
2.2、进程与线程
进程︰是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。
线程︰线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。
简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程
2.3、创建线程类
主线程:执行主(main)方法的线程
方法一:创建Thread类的子类
实现步骤:
1.创建一个Thread类的子类
2.在Thread类的子类中重写Thread类中的run方法,设置线程任务(开启线程要做什么?)
3.创建Thread类的子类对象
4.调用Thread类中的方法start方法,开启新的线程,执行run方法
void start()使该线程开始执行;Java虚拟机调用该线程的run方法。
结果是两个线程并发地运行
当前线程〈main线程)和另一个线程(创建的新线程,执行其run 方法)。
多次启动一个线程是非法的。特判是当线程已经结束执行后,不能再重新启动。
public class MyThread extends Thread{
//2.在Thread类的子类中重写Thread类中的run方法,设置线程任务(开启线程要做什么?)
@override
public void run() {
for (int i =0; i <20 ; i++) {syem.out.println( "run : "+i);
}
public class Demoe1Thread {
public static void main(Sstring[ ] args) {
//3.创建Thread类的子类对象
MyThread mt = new MyThread();
//4.调用Thread类中的方法start方法,开启新的线程,执行run方法
mt.start();
}
}
方法二:实现Runnable接口
实现步骤:
1.创建一个RunnabLe接口的实现类
2.在实现类中重写Runnable接口的run方法,设置线程任务
3.创建一个Runnable接口的实现类对象
4.创建Thread类对象,构造方法中传递RunnabLe接口的实现类对象
5.调用Thread类中的start方法,开启新的线程执行run方法
public class RunnableImpl implements Runnable{
//2.在实现类中重写Runnable接口的run方法,设置线程任务@override
public void run() {
for(int i =0; i <20 ; i++)
System.out.println( Thread.currentThread().getName()+"-->"+i);
}
}
public class Demo01Runnable {
public static void main(string[]args) {
//3.创建一个Runnable接口的实现类对象
RunnableImpl run = new RunnableImpl();
//4 .创建Thread类对象,构造方法中传递Runnable接口的实现类对象
Thread t = new Thread(run)
//5.调用Thread类中的start方法,开启新的线程执行run方法
t.start();
}
}
Thread和Runnable的区别
实现Runnable接口创建多线程程序的好处:
- 避免了单继承的局限性
一个类只能继承一个类(一个人只能有一个亲爹),类继承了Thread类就不能继承其他的类、如果实现了Runnable接口,还可以继承其他的类,实现其他的接口 - 增强了程序的扩展性,降低了程序的耦合性(解耦)
实现Runnable接口的方式,把设置线程任务和开启新线程进行了分离(解耦)
2.4、Thread类方法
String getName() | 返回该线程的名称 |
---|---|
static Thread currentThread() | 返回对当前正在执行的线程对象的引用 |
void setName( String name) | 设置名字 |
public static void sleep(Long millis) | 使当前正在执行的线程以指定的毫秒数暂停 |