JAVA基础知识
1.I/O
一.File类
(1)
java.io.File
类:文件和文件目录路径的抽象表示形式,与平台无关(2)
File
类中涉及到关于文件或文件目录的创建、删除、重命名、修改时间、文件大小等方法,并未涉及到写入或读取文件内容的操作。如果需要读取或写入文件内容,必须使用IO
流来完成。
(1)File类的常用构造方法:
- public File(String pathname) 以pathname为路径创建File对象,可以是绝对路径或者相对路径,如果pathname是相对路径,则默认的当前路径在系统属性user.dir中存储。
- public File(String parent,String child) 以parent为父路径,child为子路径创建File对象。
- public File(File parent,String child) 根据一个父File对象和子文件路径创建File对象
public class FileDemo {
public static void main(String[] args) {
// 方式一:根据文件路径名创建 File 实例
File file1 = new File("test.txt");
// 方式二
File file2 = new File("parent", "child");
// 方式三
File parent = new File("parent");
File file3 = new File(parent, "child");
}
}
(2)File类的常用方法:
- public String getAbsolutePath() 获取绝对路径
- public String getPath() 获取路径
- public String getName() 获取名称
- public String getParent() 获取上层文件目录路径。若无,返回null
- public long length() 获取文件长度(即:字节数)。不能获取目录的长度。
- public long lastModified() 获取最后一次的修改时间,毫秒值
- public String[] list() 获取指定目录下的所有文件或者文件目录的字符串数组
- public File[] listFiles() 获取指定目录下的所有文件或者文件目录的File对象数组
- public boolean renameTo(File dest) 把文件重命名为指定的文件路径
- public boolean isDirectory() 判断是否是文件目录
- public boolean isFile() 判断是否是文件
- public boolean exists() 判断是否存在
- public boolean canRead() 判断是否可读
- public boolean canWrite() 判断是否可写
- public boolean isHidden() 判断是否隐藏
- public boolean createNewFile() 创建文件。若文件存在,则不创建,返回false
- public boolean mkdir() 创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。
- public boolean mkdirs() 创建文件目录。如果上层文件目录不存在,一并创建
- public boolean delete() 删除文件或者文件夹
(3)详细的创建File
- boolean createNewFile() :当且仅当不存在此文件时,就会创建一个新的空文件。
- boolean mkdir() :当且仅当不存在此文件夹时,就会创建此文件夹(仅限以及目录)
- boolean mkdirs() :创建文件夹(可多级目录)
-
import java.io.File; public class Main{ public static void main(String[] args) throws Exception{ // 方式一 File file1 = new File("test.txt"); boolean b1 = file1.exists(); System.out.println(b1); // 方式二 File file2 = new File("parent", "child"); boolean b2 = file2.exists(); System.out.println(b2); // 方式三 File parent = new File("parent"); File file3 = new File(parent, "child"); boolean b3 = file3.exists(); System.out.println(b3); //因为有了createNewFile() boolean b = file1.createNewFile(); System.out.println(b); } }
原本test.txt不存在,我们把它创建出来了
第一次调用结果,返回“true”。而且,在项目路径下也创建了一个文件“test.txt”。结果:创建文件成功。
那么,当这个文件已存在时,再次调用那方法会有什么结果呢?
很显然,返回“false”,创建失败。因为此文件已经存在。
(4)详细的删除文件
- boolean delete() :删除存在的文件或文件夹。
如果文件/文件夹存在,则删除成功;否则,删除失败,并不会抛出异常哈~
(5)遍历目录下的文件
File类中提供了list()方法,可以获取目录下所有文件和目录的名称。
对目录下的文件遍历可分为以下3种方式:
- 遍历指定目录下的所有文件
- 遍历指定目录下指定扩展名的文件
- 遍历包括子目录中的文件在内的所有文件
1.遍历指定目录下的所有文件
首先要去D盘里面创建相关文件
import java.io.File;
public class Main{
public static void main(String[] args) throws Exception{
// 方式一
File file = new File("D:\\javase03");
fileDir(file);
}
private static void fileDir(File dir) {
File[] files=dir.listFiles();
for (File file:files){
if (file.isDirectory()){
fileDir(file);
}
System.out.println(file.getAbsolutePath());
}
}
}
2.遍历指定目录下指定扩展名的文件
File类提供了一个重载的list()方法,该方法接收了一个FilenameFilter类型的参数。FilenameFilter是一个接口,被称作文件过滤器,其中定义了抽象方法accept()用于依次对指定File的所有子目录或文件进行迭代。
import java.io.File;
import java.io.FilenameFilter;
public class Main{
public static void main(String[] args) throws Exception{
//创建File对象
File file = new File("D:\\javase03");
//创建文件过滤器对象
FilenameFilter filter=new FilenameFilter() {
@Override
//实现accept()方法
public boolean accept(File dir, String name) {
File currFile=new File(dir,name);
//如果文件名以.java结尾,则返回true,否则返回false
if(currFile.isFile()&&name.endsWith(".java")) {
return true;
}else{
return false;
}
}
};
if(file.exists()){//判断File对象对应的目录是否存在
String[] lists=file.list(filter);//获得过滤后的所有文件名数组
for(String name:lists){
System.out.println(name);
}
}
}
}
3.遍历包括子目录中的文件在内的所有文件
使用File类提供的另一个方法————listFiles()
import java.io.File;
//import java.io.FilenameFilter;
public class Main {
public static void main(String[] args) throws Exception {
//创建File对象
File file = new File("D:\\javase03");
fileDir(file);//调用fileDir()方法
}
private static void fileDir(File dir) {
File[] files=dir.listFiles();//获得表示目录下所有文件的数组
for(File file:files){//遍历所有子目录和文件
if(file.isDirectory()){
fileDir(file);//如果是目录,则递归调用fileDir()
}
System.out.println(file.getAbsolutePath());//输出文件的绝对路径
}
}
}
(6)删除文件及目录
调用File类的delete()方法。File类的delete()方法只能删除一个指定的文件;加入File对象代表一个目录,并且这个目录下包含子目录或文件,则File类的delete()方法不允许直接删除这个目录。在这种情况下,需要通过递归的方式将整个目录以及目录下的文件全部删除。
import java.io.File;
//import java.io.FilenameFilter;
public class Main {
public static void main(String[] args) throws Exception {
//创建File对象
File file = new File("D:\\javase03");
deleteDir(file);//调用deleteDir()方法
System.out.println("删除成功!");
}
private static void deleteDir(File dir) {
if(dir.exists()){//判断传入的File对象是否存在
File[] files=dir.listFiles();//得到File数组
for(File file:files){//遍历所有子目录和文件
if(file.isDirectory()){
deleteDir(file);//如果是目录,则递归调用deleteDir()方法
}else{
//如果是文件,则直接删除
file.delete();
}
}
//删除一个目录里的所有文件后,就删除这个目录
dir.delete();
}
}
}
//运行后:就会发现D盘里没有javase03这个文件了
二.字节流
JDK提供了两个抽象类————InputStream和OutputStream,它们是字节流的顶级父类,所有的字节输入流都继承InputStream,所有的字节输出流都继承OutputStream。
(1)字节流读文件
1)导入相关的类
import java.io.IOException;
import java.io.InputStream;
import java.io.FileInputStream;
2)构造一个文件输入流对象
InputStream fileObject = new FileInputStream("text.txt");//此时的文件输入流对象fileObject就和源数据源(text.txt)关联起来。
3)利用文件输入流类的方法读取文本文件中的数据
fileObject.available();//可读取的字节
fileObject.read();//读取文件的数据
4)关闭文件输入流对象
fileObject.close();
代码典例如下:
import java.io.*;
public class Main{
public static void main(String[] args) throws Exception{
//创建一个文件字节输入流,并指定源文件名称
FileInputStream in=new FileInputStream("test.txt");
int b=0;//定义int类型的变量b,用于记住每次读取的一字节
while(true){
b=in.read();//变量b记住读取的一字节
if(b==-1){//如果读取的字节为-1,则跳出while循环
break;
}
System.out.println(b);//否则将b输出
}
in.close();
}
}
如出现无法查找到文件,那就在项目下加入该文件
(2)字节流写文件
1)导入相关的类
import java.io.IOException;
import java.io.InputStream;
import java.io.FileInputStream;
2)构造一个文件输入流对象
InputStream fileObject = new FileInputStream("text.txt");//此时的文件输入流对象fileObject就和源数据源(text.txt)关联起来。
3)利用文件输入流类的方法读取文本文件中的数据
fileObject.available();//可读取的字节
fileObject.read();//读取文件的数据
4)关闭文件输入流对象
fileObject.close();
import java.io.*;
public class Main{
public static void main(String[] args) throws Exception{
OutputStream out=new FileOutputStream("example.txt");
String str="教育";
byte[] b=str.getBytes();
for(int i=0;i<b.length;i++){
out.write(b[i]);
}
out.close();
}
}
使用FileOutputStream写数据时,程序自动创建了文件example.txt,并将数据写入example.txt文件。需要注意的是,如果通过FileOutputStream向一个已经存在的文件中写入数据,那么该文件中的数据会被覆盖。
若希望在已存在的文件内容之后追加新内容,则可使用FileOutputStream的构造函数FileOutputStream(String fileName,boolean append)创建文件输出流对象,并将append参数的值设置为true.
import java.io.*;
public class Main{
public static void main(String[] args) throws Exception{
OutputStream out=new FileOutputStream("example.txt",true);
String str="nihao";
byte[] b=str.getBytes();
for(int i=0;i<b.length;i++){
out.write(b[i]);
}
out.close();
}
}
(3)文件的复制
文件的复制需要通过输入流读取一个文件中的数据,再通过输出流将数据写入另一个文件。
import java.io.*;
public class Main{
public static void main(String[] args) throws Exception{
InputStream in=new FileInputStream("source/.a.png");
OutputStream out=new FileOutputStream("target/b.png");
byte[] buff=new byte[1024];
int len;
long begintime=System.currentTimeMillis();
while((len=in.read(buff))!=-1){
out.write(buff,0,len);
}
long endtime=System.currentTimeMillis();
System.out.println("复制所用时间"+(endtime-begintime));
in.close();
out.close();
}
}
三.字符流
字符流也有两个抽象的顶级父类,分别是Reader类和Writer类
Reader类的常用方法:
public int read() 从输入流中读一个字符
public int read(char[ ]cbuf) 从输入流中读最多cbuf. length个字符,存入字符数组cbuf中
public int read(char[ ]buffer,int off,int len) 从输入流中读最多len个字符,存入字符数组cbuffer中从off开始的位置
public long skip(long n) 从输入流中最多向后跳n个字符
public boolean ready() 判断流是否做好读的准备
public void mark(int read AheadLimit ) 标记输入流的当前位置
public boolean markSupported () 测试输入流是否支持mark
public void reset() 重定位输入流
public void close() 关闭输入流
Writer类的常用方法:
public void write(int c) 将单一字符c输出到流中
public void write(String str) 将字符串str输出到流中
public void write(char[]cbuf) 将字符数组cbuf输出到流
public void write(char[]cbuf,int off,int len) 将字符数组按指定的格式输出(off表示索引,len表示写入的字符数)到流中
public void flush() 将缓冲区中的数据写到文件中
public void close() 关闭输出流
(1)字符流读文件
port java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class demo {
public static void main(String[] args) throws IOException {
//定义文件路径
String str1="C:\\Users\\Administrator\\Desktop\\id.txt";
//常见字符输入流资源
FileReader fr1 = new FileReader(str1);
int ten=0;
while ((ten=fr1.read())!=-1){
//读取文件并打印
System.out.print((char)ten);
}
//释放系统资源
fr1.close();
}
}
(2)字符流写文件
Writer writer=new FileWriter("lib/1.txt");
//一次写一个字符
writer.write('好');
//字符数组
char chs[]={'黑','马','程','序','员'};
writer.write(chs,2,3);
//字符串
writer.write("好好学习");
writer.close();
(3)转换流
- Java API提供了两个转换流:
InputStreamReader
:将InputStream转换为ReaderOutputStreamWiter
:将Writer转换为OutputStream
import java.io.*;
public class Main{
public static void main(String[] args) throws Exception{
//创建字节输入流in,并指定源文件为src.txt
FileInputStream in=new FileInputStream("source。txt");
//将字节输入流in转换成字符输入流isr
InputStreamReader isr= new InputStreamReader(in);
//创建字节输出流out,并指定目标文件的是des.txt
FileOutputStream out =new FileOutputStream("des.txt");
//将字节输出流out转换成字符输出流osw
OutputStreamWriter osw=new OutputStreamWriter(out);
int ch;
while((ch=isr.read())!=-1){
osw.write(ch);//将字符数据写入des.txt文件中
}
isr.close();//关闭字符输入流,释放资源
osw.close();//关闭字符输出流,释放资源
}
}
2.JDBC
1.jdbc的概念
- JDBC(Java DataBase Connectivity:java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,它是由一组用Java语言编写的类和接口组成的。
- JDBC的作用:可以通过java代码操作数据库
2.JDBC的常用API
- Driver接口:Driver接口是所有JDBC驱动程序必须实现的接口,该接口专门提供给数据库厂商使用。需要注意的是,在编写Java应用程序时,必须把使用的数据库驱动程序(这里指MySQL驱动程序的JAR包)或类库加载到项目的classpath中。
- DriverManager类:用于加载JDBC驱动程序并且创建Java应用程序与数据库的连接。
- Connection接口
- Statement接口
- PreparedStatement接口
- ResultSet接口
3.我们直接用代码实现吧,这里我MySQL用的是HeisiSQL
首先关于HeisiSQL的详细使用我们截图体现一下:
首先新建一个连接,我这里已经写好了,我使用的是localhost,用户名:root
进去之后就是新建数据库了
数据库建完就是建表
建完表以后就是建立表的属性信息,也可以查询里面用代码写
建立表里面的相关属性信息代码是这样子的
CREATE DATABASE test;USE test;
CREATE TABLE teacher
(
number INT,
NAME CHAR(50),
age int
);
然后建立完相关信息后,我再用的查询插入信息,查询结果具体如下:
接下来就是撰写JDBC的代码与MySQL里面的数据连通:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class ConnMySQL {
public static void main(String args[]) throws Exception
{
Statement stmt=null;
ResultSet rs=null;
Connection conn=null;
try{
//1.注册数据库的驱动程序
Class.forName("com.mysql.cj.jdbc.Driver");//这是一个MySQL与JDBC的驱动程序类名,是固定的,初学者会认为cj是命名,从而修改,但这是固定的
//通过DriverManager获取数据库连接
String url="jdbc:mysql://localhost:3306/test"+"?serverTimezone=GMT%2B8&useSSL=false";
String username="root";//数据库用户名
String password="123456";//数据库密码
conn=DriverManager.getConnection(url,username,password);
//通过Connection对象获取Statement对象
stmt=conn.createStatement();
//使用Statement执行SQL语句
String sql="select * from teacher";
rs=stmt.executeQuery(sql);
//操作结果集
System.out.println("number name age");
while(rs.next()){
String number=rs.getString("number");//通过列名获取指定列的值
String name=rs.getString("name");
int age=rs.getInt("age");
System.out.println(number+" "+name+" "+age);
}
}catch (Exception e){
e.printStackTrace();
}finally {
//回收数据库资源
if (rs!=null){
try{
rs.close();
}catch (SQLException e){
e.printStackTrace();
}
rs=null;
}
if(stmt!=null){
try {
stmt.close();
}catch (SQLException e){
e.printStackTrace();
}
stmt=null;
}
if (conn!=null){
try {
conn.close();
}catch (SQLException e){
e.printStackTrace();
}
conn=null;
}
}
}
}
之后运行结果如下:
3.多线程
多线程就是指一个应用程序中有多种并发执行的线索,每条线索都被称作一个线程,它们会交替执行,彼此可以通信。
一.进程与线程
进程是系统进行资源分配和调度的基本单位,是操作系统结构的基础。程序一旦运行就是进程,进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响
线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位
总结:每个运行的程序都是一个进程,在一个进程中还可以由多个执行单元同时执行,这些执行单元可以看作程序执行的线程。每一个进程中都至少存在一个线程。
二.多线程的创建方式
(1)继承java.lang包中的Thread类,重写Thread类的run()方法,在run()方法中实现多线程代码
/*
1.创建一个继承于Thread类的子类
2.重写Thread类的run()
3.创建Thread类的子类的对象
4.通过此对象调用start()
注意:①调动当前线程,②调用当前线程run()
*/
//具体操作如下:
//1.创建一个继承于Thread类的子类
class MyThread extends Thread{
//2.重写Thread类的run()
@Override
public void run() {
for (int i=0;i<100;i++){
if(i%2==0){
System.out.println(i);
}
}
}
}
public class Exaample {
public static void main(String[] args){
//3.创建Thread类的子类的对象
MyThread t1=new MyThread();
//通过此对象调用start()
t1.start();
}
}
(2)实现java.lang.Runnable接口,在run()方法中实现多线程代码
/*
1.创建一个实现Runnable接口的类
2.实现Runnable接口中的run()---》将此线程要执行的操作,声明在此方法体中
3.创建当前实现类的对象
4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
5.Thread类的实例调用start():
注意:①启动线程,②调用当前线程run()
*/
//具体操作如下:
//1.创建一个实现Runnable接口的类
class MyThread implements Runnable{
//2.实现Runnable接口中的run()---》将此线程要执行的操作,声明在此方法体中
public void run() {
for (int i=0;i<100;i++){
if(i%2==0){
System.out.println(i);
}
}
}
}
public class Exaample {
public static void main(String[] args){
//3.创建当前实现类的对象
MyThread t1=new MyThread();
//4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
Thread thread=new Thread(t1);
//Thread类的实例调用start()
thread.start();
}
}
(3)实现java.util.concurrent.Callable接口,重写call()方法,并使用Future接口获取call()方法返回的结果。
import java.util.concurrent.*;
//定义一个实现Callable接口的实现类
class MyThread implements Callable<Object>{
//重写Callable接口的call()方法
public Object call() throws Exception {
int i=0;
while(i++<5){
System.out.println(Thread.currentThread().getName()+"的call()方法在运行");
}
return i;
}
}
public class Exaample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//创建Callable接口的实例对象
MyThread myThread = new MyThread();
//使用FutureTask封装Mythread类
FutureTask<Object> ft1 = new FutureTask<Object>(myThread);
//使用Thread(Runnable target,String name)构造方法创建线程对象
Thread thread1 = new Thread(ft1, "thread");
//调用线程对象的start()方法启动线程
thread1.start();
//通过FutureTask对象的方法管理返回值
System.out.println(Thread.currentThread().getName()+"的返回结果:"+ft1.get());
int a=0;
while(a++<5){
System.out.println("main()的方法 在执行");
}
}
}