一.IO
IO解决问题: 解决设备与设备之间 的数据传输问题。 比如: 硬盘--->内存 内存----->硬盘
1.字节流:
输入字节流:
---------| InputStream 所有输入字节流的基类。 抽象类。
------------| FileInputStream 读取文件的输入字节流。
------------| BufferedInputStream 缓冲输入字节流。 该类内部其实就是维护了一个8kb字节数组而已。 该类出现的目的是为了提高读取文件数据的效率。
输出字节流:
---------| OutputStream 所有输出字节流的基类。 抽象类。
------------| FileOutputStream 向文件输出数据 的输出字节流。
------------| BufferedOutputStream 缓冲输出字节流。 该类出现的目的是为了提高向文件写数据的效率。 该类内部其实也是维护了一个8kb的字节数组而已。
什么情况使用字节流: 读取到数据不需要经过编码或者解码的情况情况下这时候使用字节流。比如:图片数据
2.字符流 = 字节流 + 编码(解码)
字符流:
输入字符流
--------| Reader 所有输入字符流的基类。 抽象类。
-----------| FileReader 读取文件字符的输入字符流。
-----------| BufferedReader 缓冲输入字符流。 该类出现的目的是为了提高读取文件字符的效率并且拓展了功能(readLine()),它内部 其实就是维护了一个8192个长度的字符数组。
输出字符流
-------| Writer 所有输出字符流的基类。 抽象类。
------------| FileWriter 向文件输出字符数据的输出字符流。
---------------| BufferedWriter 缓冲输出字符流。该类出现的目的是为了提高写文件字符的效率并且拓展了功能(newLine())。
什么情况下使用字符流:如果读写的都是字符数据,这时候我们就使用字符流。
3.转换流:
输入字节流的转换流 输入字节流---------输入字符流
InputSrteamReader输出字节流的转换流
OutputStreamWriter
转换流的作用:
1. 可以把对应的字节流转换成字符流使用。
2. 可以指定码表进行读写文件的数据。
FileReader, FileWriter这两个类默认是使用的是gbk编码 表。不能由你来指定码表读写文件数据。
public class Demo1 {
public static void main(String[] args) throws Exception {
// testInput();
// writeFile();
readFile();
}
public static void readFile() throws IOException{
//建立文件与程序的输入数据通道
FileInputStream fileInputStream = new FileInputStream("F:\\a.txt");
//创建输入字节流的转换流并且指定码表进行读取
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,"utf-8");
int content = 0;
while((content = inputStreamReader.read())!=-1){
System.out.println((char)content);
}
//关闭资源
inputStreamReader.close();
/*FileReader fileReader = new FileReader("F:\\a.txt"); //默认使用的是gbk码表
int content = 0;
while((content = fileReader.read())!=-1){
System.out.print((char)content);
}
//关闭资源
fileReader.close();*/
}
//指定使用utf-8码表把数据写出到文件上。
public static void writeFile() throws IOException{
//建立了文件与程序的数据 通道
FileOutputStream fileOutputStream = new FileOutputStream("F:\\a.txt");
//创建一个输出字节流的转换流并且指定码表进行写数据
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream,"utf-8");
outputStreamWriter.write("大家好"); //中文在utf-8码表中占三个字节。
//关闭资源
outputStreamWriter.close();
}
public static void testOutput() throws Exception{
Socket socket = new Socket(InetAddress.getLocalHost(),9090);
//获取到socket的输出流对象。
OutputStream outputStream = socket.getOutputStream();
//把输出字节流转换成输出字符流
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
outputStreamWriter.write("不饿!");
}
public static void testInput() throws Exception{
InputStream in = System.in;
// int content = in.read(); // 每次只会读取到一个字节的数据
//需要把字节流转换成字符流使用。
InputStreamReader inputStreamReader = new InputStreamReader(in);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
System.out.println(bufferedReader.readLine());
}
}
二,多线程
多线程的好处: 多线程解决了在一个进程中同时可以执行多个任务代码的问题。
自定义线程的创建方式:
方式一:继承Thread.
1. 自定义一个类继承Thread类。
2. 重写Thread的run方法,把自定义线程的任务代码定义在run方法上。
3. 创建Thread子类的对象,并且调用start方法启动一个线程。
方式二: 实现Runnable接口。
1. 自定义一个类实现Runnable接口。
2. 实现Runnable接口中的run方法,把自定义线程的任务代码定义在run方法上。
3. 创建Runable实现类 的对象。
4. 创建Thread对象,并且把Runnable实现类的对象作为参数传递。
5. 调用Thread对象的start方法开启线程。
线程安全 问题的解决方案:
线程安全问题出现 的根本原因:
1. 必须要存在两个或者两个以上的线程共享着一个资源。
2. 操作共享资源的代码必须有两句或者两句以上。
1. 同步代码块
synchronized(锁){
需要被同步的代码
}
2. 同步函数。
修饰符 synchronized 返回值类型 函数名(形参列表..){
}
注意:
1. 同步代码块的锁可以是任意的对象。 同步函数的锁是固定 的,非静态函数的锁对象是this对象。 静态函数的锁对象是class对象。
2. 锁对象必须是多线程共享的对象,否则锁不住。
3. 在同步代码块或者是同步函数中调用sleep方法是不会释放锁对象的,如果是调用了wait方法是会释放锁对象的。
public class Demo1 extends Thread {
public Demo1(String name){
super(name);
}
@Override
public void run() {
for(int i = 0 ; i< 100 ; i++){
System.out.println(Thread.currentThread().getName()+":"+ i);
}
}
public static void main(String[] args) {
Demo1 d = new Demo1("小孩");
d.start(); //开启线程。 线程一旦开启就会指定run方法中 的代码。
for(int i = 0 ; i< 100 ; i++){
System.out.println(Thread.currentThread().getName()+":"+ i);
}
}
}