Java系列之:读写文件、Callable接口、Runnable接口、线程池
- 读取一个文件中的数据,排序后的结果写入到另一个文件中
- 读取一个文件的内容,并将内容逐行写入到另一个文件中
- 泛型接口Callable
- 函数式接口Runnable
- 线程池
读取一个文件中的数据,排序后的结果写入到另一个文件中
这段代码的作用是读取一个文件中的数据,对数据进行排序,然后将排序后的结果写入到另一个文件中。
- 创建了一个
BufferedReader
对象bufferedReader
,用于读取输入文件。BufferedReader
是一个字符输入流,它继承自Reader
类,可以逐行读取文本数据。 - 创建了一个
BufferedWriter
对象bufferedWriter
,用于写入输出文件。BufferedWriter
是一个字符输出流,它继承自Writer
类,可以将文本数据写入到文件中。 - 通过
for
循环遍历排序后的data
列表,将每行数据写入到输出文件中,并使用bufferedWriter.newLine()
方法在每行数据之间添加一个换行符。
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
public class BufferReaderWriter {
public static void main(String[] args) throws IOException {
String filePath = "{输入文件名}";
String outputFile = "{输出文件名}";
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(outputFile));
ArrayList<String> data = new ArrayList<>();
String line;
while((line = bufferedReader.readLine()) != null){
data.add(line);
}
Collections.sort(data);
for (String ln : data){
bufferedWriter.write(ln);
bufferedWriter.newLine();
}
bufferedReader.close();
bufferedWriter.close();
}}
读取一个文件的内容,并将内容逐行写入到另一个文件中
代码的作用是读取一个文件的内容,并将内容逐行写入到另一个文件中。
- 使用
FileInputStream
类创建了一个输入流对象fis
,并将其与file
关联起来。FileInputStream
是一个字节输入流,用于从文件中读取字节数据。 - 创建了一个
BufferedReader
对象br
,它使用InputStreamReader
将字节输入流fis
转换为字符输入流。BufferedReader
是一个字符输入流,用于逐行读取文本数据。 - 创建了一个
FileOutputStream
对象fos
和一个OutputStreamWriter
对象osw
,用于写入目标文件。FileOutputStream
是一个字节输出流,用于将字节数据写入文件。OutputStreamWriter
是一个字符输出流,用于将字符数据转换为字节数据并写入文件。
import java.io.*;
public class FileInputStreamTest {
public static void main(String[] args) throws IOException {
// FileInputStream fileInputStream = new FileInputStream(("{文件路径}/tetest_debezium.conf"));
//read()每次读取一个字节,没有数据返回-1
// int read = fileInputStream.read();
// System.out.println((char)read);
//循环读取
// int b;
// while((b = fileInputStream.read()) !=-1){
// System.out.println((char) b);
// }
//每次读取多个字节
// byte[] buffer = new byte[1024*8];
// int read1 = fileInputStream.read(buffer);
// String s = new String(buffer);
// System.out.println(s);
// System.out.println("读取的字节数量是: "+read1);
//循环读取
// byte[] buffer = new byte[1024*8];
// int len; //记住每次读取多少字节
//
// while((len = fileInputStream.read(buffer)) !=-1){
// //读取多少,倒出多少
// String s = new String(buffer, 0, len);
// System.out.print(s);
// }
// fileInputStream.close();
String filePath = "{文件路径}/tetest_debezium.conf";
// 创建File对象
File file = new File(filePath);
// 使用try-with-resources语句创建FileInputStream和BufferedReader
FileInputStream fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
// // 读取文件内容
// String line;
// StringBuilder content = new StringBuilder();
// while ((line = br.readLine()) != null) {
// content.append(line);
// content.append(System.lineSeparator());
// }
// // 打印文件内容
// System.out.println(content.toString());
//换行符
// os.write("\r\n".getBytes())
try(
// 创建输出流写入目标conf文件
FileOutputStream fos = new FileOutputStream("{}/tetest_debezium.conf");
//把原始宕字节输出流,按照指定的字符集编码转换成字符输出转换流
OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
) {
//把字符输出流包装成缓冲字符输出流
BufferedWriter bw = new BufferedWriter(osw);
// 逐行读取原始conf文件内容,并写入目标conf文件
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
}
br.close();
bw.close();
System.out.println("内容已经成功写入目标conf文件。");
} catch (IOException e){
e.printStackTrace();
}
}}
泛型接口Callable
- 在
DebeziumCallable
类中,实现了Callable
接口的call()
方法。在call()
方法中,使用for
循环计算从1到n
的和,并将结果以字符串的形式返回。在返回的字符串中,使用Thread.currentThread().getName()
方法获取当前线程的名称,并将其与计算结果一起输出。 Callable
接口是一个泛型接口,它定义了一个call()
方法,可以在其中编写并发计算任务的代码。Callable
接口的call()
方法返回一个泛型类型的值,用于表示计算的结果。
import java.util.concurrent.Callable;
public class DebeziumCallable implements Callable <String>{
private int n;
public DebeziumCallable(int n){
this.n = n;
}
@Override
public String call() throws Exception {
int sum = 0;
for (int i =1 ; i <= n; i++){
sum +=i;
}
return Thread.currentThread().getName() + "求出了1-"+n+"的和是:"+sum;
}
}
函数式接口Runnable
- 在
DebeziumRunnable
类中,重写了Runnable
接口的run()
方法。在run()
方法中,首先使用Thread.currentThread().getName()
方法获取当前线程的名称,并将其与字符串" ==> 输出666~~"一起输出。 - 然后,使用
Thread.sleep(5)
方法暂停当前线程的执行,使其休眠5毫秒。 Runnable
接口是一个函数式接口,用于定义多线程任务的执行逻辑。它只包含一个抽象方法run()
,该方法没有返回值。通过实现Runnable
接口并重写run()
方法,可以在多线程环境中执行自定义的任务逻辑。
import lombok.SneakyThrows;
public class DebeziumRunnable implements Runnable{
@SneakyThrows
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " ==> 输出666~~");
Thread.sleep(5);
}
}
线程池
ThreadPoolExecutor
的构造方法接受多个参数,分别是核心线程数、最大线程数、线程空闲时间、时间单位、任务队列、线程工厂和拒绝策略。这些参数用于配置线程池的行为。- 接下来,创建了一个
DebeziumRunnable
对象target
,作为任务对象。 - 然后,通过
pool.execute(target)
方法将任务提交给线程池执行。execute()
方法用于提交一个Runnable
任务给线程池执行。线程池会自动创建一个新线程来处理任务,并执行DebeziumRunnable
类中定义的任务逻辑。 - 还通过
pool.submit(new DebeziumCallable(100))
方法将一个Callable
任务提交给线程池执行。submit()
方法用于提交一个Callable
任务给线程池执行,并返回一个Future
对象。Future
对象可以用于获取任务执行的结果。 - 最后,通过
submit.get()
方法获取Future
对象的结果,并将结果打印输出。 - 在代码的最后,创建了另一个线程池
executorServicePool
,通过Executors.newFixedThreadPool(3)
方法创建一个固定大小的线程池。newFixedThreadPool()
方法用于创建一个固定大小的线程池,其中指定的参数表示线程池中的线程数量。
import java.util.concurrent.*;
public class ThreadPoolTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService pool = new ThreadPoolExecutor(3, 5, 8, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
Runnable target = new DebeziumRunnable();
pool.execute(target); //线程池会自动创建一个新线程,自动处理这个任务,自动执行
pool.execute(target);
pool.execute(target);
// pool.shutdown(); //等着线程池的任务全部执行完毕之后再关闭线程池
Future<String> submit1 = pool.submit(new DebeziumCallable(100));
Future<String> submit2 = pool.submit(new DebeziumCallable(200));
Future<String> submit3 = pool.submit(new DebeziumCallable(300));
Future<String> submit4 = pool.submit(new DebeziumCallable(400));
System.out.println(submit1.get());
System.out.println(submit2.get());
System.out.println(submit3.get());
System.out.println(submit4.get());
ExecutorService executorServicePool = Executors.newFixedThreadPool(3);
//计算密集型宕任务:核心线程数量 = cpu的核数+1
//IO密集型的任务:核心线程数量 =CPU核数*2
}
}