AUPE学习第四章------文件和目录

本文详细介绍了如何使用 C 语言获取文件属性、权限、类型等信息,并通过实例展示了如何利用 stat 函数、chmod 函数等进行文件权限管理与目录操作。主要内容包括文件类型识别、设置与检查用户ID与组ID、文件访问权限、umask 设置、chmod 与 fchmod 函数应用、chown、fchown 和 lchown 函数使用、文件长度管理、文件截短、文件访问时间更新、目录读取与切换、特殊设备文件处理、文件访问权限位总结以及常见文件系统操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果我们希望知道文件的各种信息和特征,stat结构可以包含文件的所有属性。

我们可以通过下面三个函数来得到文件的所有属性和信息:

int    stat(const   char *restrict   pathname,   struct   stat  *restrict   buf);

int    fstat(int    filedes,  struct stat   *buf);

int    lstat(const  char *restrict   pathname,   struct  stat   *restrict    buf);

返回值:若成功返回0,若失败返回-1。

其中buf参数结构式我们必须提供来存储文件信息的。

structstat.c:

struct stat
{
mode_t     st_mode;
ino_t      st_ino;
dev_t      st_dev;
dev_t      st_rdev;
nlink_t    st_nlink;
uid_t      st_uid;
gid_t      st_git;
off_t      st_size;
time_t     st_atime;
time_t     st_mtime;
time_t     st_ctime;
}

4.3文件类型

普通文件,目录文件,快特殊文件,字符特殊文件,FIFO,套接字(socket),符号链接。

文件类型信息包含在stat结构的st_mode成员中。可以用下面的宏来确认文件类型,st_mode是他们的参数。

<sys/stat.h>中的文件类型宏

S_ISREG()         普通文件

S_ISDIR()           目录文件

S_ISCHR()         字符特殊文件

S_ISBLK()          块特殊文件

S_ISFIFO()         管道或者FIFO

S_ISLNK()          符号链接

S_ISSOCK()      套接字

下面的程序对每个命令行参数打印文件类型:

stattest.c:

#include "apue.h"

int main(int argc, char *argv[])
{
    int i;
    struct stat buf;
    char *ptr;
    for (i =1; i < argc; i++)
    {
        printf("%s: ", argv[i]);
        if (lstat(argv[i], &buf) < 0)
        {
            err_ret("lstat error");
            continue;
        }
    if (S_ISREG(buf.st_mode))
        ptr = "regular";
    else if (S_ISDIR(buf.st_mode))
        ptr = "directory";
    else if (S_ISCHR(buf.st_mode))
        ptr = "character special";
    else if (S_ISBLK(buf.st_mode))
        ptr = "block special";
    else if (S_ISFIFO(buf.st_mode))
        ptr = "FIFO";
    else if (S_ISLNK(buf.st_mode))
        ptr = "symbolic link";
    else if (S_ISSOCK(buf.st_mode))
        ptr = "socket";
    else
        ptr = "** unknown mode **";
    printf("%s\n",ptr);
    }
    exit(0);
}

运行结果如下:

[root@localhost apue]# gcc -o stattest.out stattest.c 
[root@localhost apue]# ./ stattest.out  /etc/passwd /etc /dev/initctl /dev/log\
> /dev/tty /dev/scsi/host0/bus0/target0/lun0/cd /dev/cdrom
bash: ./: is a directory
[root@localhost apue]# ./stattest.out  /etc/passwd /etc /dev/initctl /dev/log/dev/tty /dev/scsi/host0/bus0/target0/lun0/cd /dev/cdrom
/etc/passwd: regular
/etc: directory
/dev/initctl: FIFO
/dev/log/dev/tty: lstat error: Not a directory
/dev/scsi/host0/bus0/target0/lun0/cd: lstat error: No such file or directory
/dev/cdrom: symbolic link
[root@localhost apue]# ./stattest.out  /etc/passwd /etc /dev/initctl /dev/log /dev/tty /dev/scsi/host0/bus0/target0/lun0/cd /dev/cdrom
/etc/passwd: regular
/etc: directory
/dev/initctl: FIFO
/dev/log: socket
/dev/tty: character special
/dev/scsi/host0/bus0/target0/lun0/cd: lstat error: No such file or directory
/dev/cdrom: symbolic link

4.4设置用户ID和设置组ID

与进程相关的ID共有六个或者更多。实际用户ID,实际组ID,有效用户ID,有效组ID,附加组ID,保存的设置用户ID,保存的设置组ID。

通常有效用户ID等于实际用户ID,有效组ID等于实际组ID。分别由stat结构中的st_uid和st_gid来确定。

4.5文件访问权限

stat结构中的st_mode值也包含针对文件的访问权限位。所有的文件类型都有访问权限。

有效用户ID就是执行这个进程的用户的ID,实际用户ID就是文件的所有者。组是同样的结果。

当我们用open或者creat,mkdir新建一个目录或者文件的时候,文件的所有者ID就是进程的有效用户ID,

组ID要么是有效组ID或者它所在目录的ID。

4.7 access函数

我们有时需要测试实际用户和组对文件的访问权限,access函数是按实际用户ID和组ID进行访问权限测试的。

int   access(const  char   *pathname,   int   mode);

返回:成功返回0,错误返回-1。

mode参数是按下面的几个值按位或。

mode          说明

R_OK          测试读权限

R_OK         测试写权限

X_OK          测试执行权限

F_OK          测试文件是否存在

access函数实例:

access.c:

#include "apue.h"
#include <fcntl.h>

int main(int argc, char *argv[])
{
    if (argc != 2)
        err_quit("usage:a.out <pathname>");
    if (access(argv[1], R_OK) < 0)
        err_ret("access error for %s", argv[1]);
    else
        printf("read access ok\n");
    if (open(argv[1], O_RDONLY) < 0)
        err_ret("open error for %s", argv[1]);
    else
        printf("open for reading ok\n");
    exit(0);
}

执行结果:

[root@localhost apue]# gcc -o access.out access.c 
[root@localhost apue]# ls -l access.out 
-rwxr-xr-x 1 root root 7025 12-28 17:51 access.out
[root@localhost apue]# ./access.out  access.out
read access ok
open for reading ok
[root@localhost apue]# ./access.out  /etc/shadow
read access ok
open for reading ok
[root@localhost apue]# su - huangcd
[huangcd@localhost ~]$ cd /apue
[huangcd@localhost apue]$ ./access.out  /etc/shadow
access error for /etc/shadow: Permission denied
open error for /etc/shadow: Permission denied

4.8umask函数

umask函数用于设置创建文件的默认权限。
mode_t     umask(mode_t   cmask);
返回:返回以前的权限对应的数字。
cmask对应于下面的一个或者多个的或。

st_mode mask

Meaning

S_IRUSR

user-read

S_IWUSR

user-write

S_IXUSR

user-execute

S_IRGRP

group-read

S_IWGRP

group-write

S_IXGRP

group-execute

S_IROTH

other-read

S_IWOTH

other-write

S_IXOTH

other-execute

umask函数实例:

#include "apue.h"
#include <fcntl.h>

#define RWRWRW (S_IRUSR|S_IWUSR|S_IWGRP|S_IRGRP|S_IROTH|S_IWOTH)

int main(void)
{
    umask(0);
    if (creat("foo", RWRWRW) < 0)
        err_sys("creat error for foo");
    umask(S_IWGRP|S_IRGRP|S_IROTH|S_IWOTH);
    if (creat("bar", RWRWRW) < 0)
        err_sys("creat error for bar");
    exit(0);
}

我们可以从结果发现,umask设置的屏蔽位已经覆盖了creat函数设置的屏蔽位。

运行结果:

[huangcd@localhost apue]$ gcc -o umasktest.out umasktest.c 
[huangcd@localhost apue]$ umask
0002
[huangcd@localhost apue]$ ./umasktest.out 
[huangcd@localhost apue]$ ls -l foo bar
-rw------- 1 huangcd huangcd 0 12-28 18:20 bar
-rw-rw-rw- 1 huangcd huangcd 0 12-28 18:20 foo

4.9chmod和fchmod函数

这两个函数可用用于改变现有文件的访问权限。

int   chmod(const  char  *pathname,   mode_t   mode);

int    fchmod(int    filedes,  mode_t  mode);

mode参数在下面中的一个或者多个或,在<sys/stat.h>中定义。

mode

Description

S_ISUID

set-user-ID on execution

S_ISGID

set-group-ID on execution

S_ISVTX

saved-text (sticky bit)

S_IRWXU

read, write, and execute by user (owner)

S_IRUSR

read by user (owner)

S_IWUSR

write by user (owner)

S_IXUSR

execute by user (owner)

S_IRWXG

read, write, and execute by group

S_IRGRP

read by group

S_IWGRP

write by group

S_IXGRP

execute by group

S_IRWXO

read, write, and execute by other (world)

S_IROTH

read by other (world)

S_IWOTH

write by other (world)

S_IXOTH

execute by other (world)

chmod函数实例:

chmodtest.c:

#include "apue.h"

int main(void)
{
    struct stat statbuf;
    if (stat("foo", &statbuf) < 0)
        err_sys("stat error for foo");
    /*turn on set-group-id and trun off group-execute*/
    if (chmod("foo", (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < 0)
        err_sys("chmod error for foo");
    /*set absolute mode to rw-r--r--*/
    if (chmod("bar", S_IRUSR| S_IWUSR| S_IRGRP| S_IROTH) < 0)
        err_sys("chmod error for bar");
    exit(0);
}

运行结果:

[huangcd@localhost apue]$ vim chmodtest.c
[huangcd@localhost apue]$ ls -l bar foo
-rw------- 1 huangcd huangcd 0 12-28 18:20 bar
-rw-rw-rw- 1 huangcd huangcd 0 12-28 18:20 foo
[huangcd@localhost apue]$ gcc -o chmodtest.out chmodtest.c 
[huangcd@localhost apue]$ ./chmodtest.out 
[huangcd@localhost apue]$ ls -l bar foo
-rw-r--r-- 1 huangcd huangcd 0 12-28 18:20 bar
-rw-rwSrw- 1 huangcd huangcd 0 12-28 18:20 foo

如果一个文件设置了粘住位,那么在文件第一次执行以后,保留程序正文部分的一个副本在交换区。可以通过S_ISVTX来设置粘住位。

4.11chown、fchown和lchown函数

下面几个函数可以用于更改文件的用户ID和组ID。

int   chown(const   char  *pathname,   uid_t   owner,   gid_t   group);

int   fchown(int   filedes,   uid_t   owner,  gid_t  group);

int   lchown(const   char   *pathname,   uid_t  owner,   gid_t   group);

如果参数owner和group中的任何一个值是-1,那么对应的ID不变。

4.12文件长度

stat结构成员st_size表示以字节为单位的文件长度,此字段只针对普通文件,目录文件和连接文件有效。

文件空洞是由于所设置的偏移量超过文件尾端,并写入某些数据造成的。对于没有写入的空洞,read读入的字节是0。

复制有空洞的文件的时候,所有的空洞都被填满。

4.13文件截短

我们可以通过在打开文件时设置O_TRUNC标志来将一个文件清空为0。

下面的函数可以用于文件的截短:

int    truncate(const   char   *pathname,   off_t    length);

int    ftruncate(int    filedes,   off_t   length);

这两个函数把文件的长度截短为length长。

4.19utime函数

一个文件的访问和修改时间可以用utime函数来实现。

int   utime(const  char  *pahtname,  const struct  utimebuf   *times)

参数中的time的结构如下:

struct  utimebuf{

     time_t   actime;

     time_t   modtime;

}

utime函数实例:

#include "apue.h"
#include <fcntl.h>
#include <utime.h>

int main(int argc, char *argv[])
{
    int   i,fd;
    struct stat   statbuf;
    struct utimbuf timebuf;
    for (i = 1; i< argc; i++)
    {
        if (stat(argv[i] , &statbuf) < 0)
        {
            err_ret("%s: stat errir", argv[i]);
            continue;
        }
        if ((fd = open(argv[i], O_RDWR| O_TRUNC)) < 0)
        {
            err_ret("%s: open error", argv[i]);
            continue;
        }
        close(fd);
        timebuf.actime = statbuf.st_atime;
        timebuf.modtime = statbuf.st_mtime;
        if (utime(argv[i], &timebuf) < 0)
        {
            err_ret("%s: utime error", argv[1]);
            continue;
        }
    }
    exit(0);
}

运行结果:

[root@localhost apue]# ls -l printId.out 
-rwxr-xr-x 1 root root 5241 12-25 15:42 printId.out
[root@localhost apue]# ls -ul printId.out 
-rwxr-xr-x 1 root root 5241 12-30 14:00 printId.out
[root@localhost apue]# date
2013年 12月 30日 星期一 14:20:28 CST
[root@localhost apue]# ./utimetest.out  printId.out 
[root@localhost apue]# ls -l printId.out 
-rwxr-xr-x 1 root root 0 12-25 15:42 printId.out
[root@localhost apue]# ls -ul printId.out 
-rwxr-xr-x 1 root root 0 12-30 14:20 printId.out
[root@localhost apue]# ls -cl printId.out 
-rwxr-xr-x 1 root root 0 12-30 14:20 printId.out

4.20mkdir和rmdir函数

新建一个目录,pahtname是一个空目录。mode是新建目录的权限值。

int    mkdir(const   char   *pathname,   mode_t   mode)

若成功返回0,出错返回-1。

用rmdir和删除一个目录。空目录只包含.和..这两项的目录。

int   rmdir(const  char   *pathname);

4.21读目录

我们可以通过下列函数来实现对一个目录的读取等操作:

DIR   *   opendir(const  char   *pahtname)     //成功返回指针,错误返回NULL

struct   dirent  * readdir(DIR  *dp);      //成功返回指针,错误返回目录结尾或者NULL

void    rewinddir(DIR   *dp)                   //成功返回0,错误返回-1

int       closedir( DIR  *dp)                            //成功返回0,错误返回-1.

long    telldir( DIR  *dp)                  //返回dp关联的目录中的当前位置。

void     seekdir(DIR  *dp,  long   loc)   //返回dp关联的目录中的当前位置。

这些函数都是在头文件<dirent.h>中定义的啊。结构体的定义如下:

struct  dirent{

ino_t   d_no;

char   d_name[NAME_MAX + 1]

}

DIR是一个内部结构,它用来保存当前正在被读取的目录的有关信息。

由opendir函数返回DIR结构的指针由其他五个函数操作。

4.22 chdir、fchdir和getcwp函数

每个进程都有一个当前工作目录,次目录是搜索所有相对路径名的起点。当前工作目录是进程的一个属性。

进程通过调用chdir和fchdir函数可以更改当前工作目录。

int   chdir(const   char  *pahtname)

int   fchdir(int filedes)

若成功返回0,若错误则返回-1。参数是指定的新的工作目录。

chdir函数实例:

chdirtest.c:

#include "apue.h"

int main(void)
{
    if (chdir("/tmp") < 0)
        err_sys("chdir failed");
    printf("chdir to /tmp succeeded\n");
    exit(0);
}

执行结果:

[root@localhost apue]# gcc -o chdirtest.out chdirtest.c 
[root@localhost apue]# pwd
/apue
[root@localhost apue]# ./chdirtest.out 
chdir to /tmp succeeded
[root@localhost apue]# pwd
/apue
我们虽然改变了当前进程的工作目录,但是并没有改变shell的工作目录,当前进程是shell进程的一个子进程。

内核中并没有保存工作目录的详细信息,只是保存了指向该目录的v节点的指针等目录本身的信息。并不保存该目录的完整路径。

我们可以通过getcwd函数来得到当前工作目录的完整路径。

char   *getcwd(char  *buf,  size_t  size)

参数一是缓冲地址的,第二个参数缓冲绝对路径长度的。

getcwd()函数实例:

getcwdtest.c:

#include "apue.h"
char* path_alloc(int* size);
int main(void)
{
    char *ptr;
    int size;
    if (chdir("/home/huangcd") < 0)
        err_sys("chdir failed");
    ptr = path_alloc(&size);  
    if (getcwd(ptr, size) == NULL)
        err_sys("getcwd failed");
    printf("cwd = %s\n", ptr);
    exit(0);
}
char * path_alloc(int *size)
{
char *p = NULL;
if(!size)
     return NULL;
p = malloc(256);
if(p)
    *size = 256;
else
    *size = 0;
return p;
}
运行结果:

root@localhost apue]# gcc -o getcwdtest.out getcwdtest.c 
[root@localhost apue]# ./getcwdtest.out 
cwd = /home/huangcd

4.23特殊设备文件

在计算机系统中,每个设备都有主设备号和此设备号。设备号用的数据类型是dev_t类型。主设备号标识设备驱动程序,次设备号标识特定的子设备。

我们可以通过major和minor这两个宏来访问主、次设备号。

系统中的每个文件的stat成员st_dev的值是文件系统的设备号。只有字符特殊文件盒块特殊文件才有st_rdev值。次值包含设计设备的设备号。

下面实例打印st_dev和st_rdev值:

devtest.c:

#include "apue.h"
#ifdef SOLARIS
#include <sys/mkdev.h>
#endif
#include <sys/sysmacros.h>

int main(int argc, char *argv[])
{
    int  i;
    struct stat buf;
    for (i = 1;i < argc; i++)
    {
        printf("%s: ",argv[i]);
        if (stat(argv[i], &buf) < 0)
        {
            err_ret("stat error");
            continue;
        }
        printf("dev = %d/%d", major(buf.st_dev), minor(buf.st_dev));
        if (S_ISCHR(buf.st_mode) || S_ISBLK(buf.st_mode))
        {
            printf("(%s) rdev = %d/%d", (S_ISCHR(buf.st_mode)) ? "character": "block", major(buf.st_rdev), minor(buf.st_rdev));
        }
        printf("\n");
    }
    exit(0);
}

运行结果:

[root@localhost apue]# gcc -o devtest.out devtest.c 
[root@localhost apue]# ./devtest.out  / /home/huangcd /dev/tty[01]
/: dev = 8/2
/home/huangcd: dev = 8/3
/dev/tty0: dev = 0/17(character) rdev = 4/0
/dev/tty1: dev = 0/17(character) rdev = 4/1

4.24文件访问权限位小结

Constant

Description

Effect on regular file

Effect on directory

S_ISUID

set-user-ID

set effective user ID on execution

(not used)

S_ISGID

set-group-ID

if group-execute set then set effective group ID on execution; otherwise enable mandatory record locking (if supported)

set group ID of new files created in directory to group ID of directory

S_ISVTX

sticky bit

control caching of file contents (if supported)

restrict removal and renaming of files in directory

S_IRUSR

user-read

user permission to read file

user permission to read directory entries

S_IWUSR

user-write

user permission to write file

user permission to remove and create files in directory

S_IXUSR

user-execute

user permission to execute file

user permission to search for given pathname in directory

S_IRGRP

group-read

group permission to read file

group permission to read directory entries

S_IWGRP

group-write

group permission to write file

group permission to remove and create files in directory

S_IXGRP

group-execute

group permission to execute file

group permission to search for given pathname in directory

S_IROTH

other-read

other permission to read file

other permission to read directory entries

S_IWOTH

other-write

other permission to write file

other permission to remove and create files in directory

S_IXOTH

other-execute

other permission to execute file

other permission to search for given pathname in directory

最后九个常量分为三组:

S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR
S_IRWXG = S_IRGRP | S_IWGRP | S_IXGRP
S_IRWXO = S_IROTH | S_IWOTH | S_IXOTH

历史记录 avater 2025-06-20 13:39:25.626 ERROR 5888 — [ main] o.s.boot.SpringApplication : Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘entityManagerFactory’ defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.GenericJDBCException: Unable to open JDBC Connection for DDL execution at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1799) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$ doGetBean$ 0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1109) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551) ~[spring-context-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:755) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:402) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:173) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:153) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:95) [spring-boot-2.3.12.RELEASE.jar:2.3.12.RELEASE] at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:172) [spring-web-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5128) [catalina.jar:9.0.37] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.37] at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:717) [catalina.jar:9.0.37] at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690) [catalina.jar:9.0.37] at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705) [catalina.jar:9.0.37] at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1133) [catalina.jar:9.0.37] at org.apache.catalina.startup.HostConfig$ DeployDirectory.run(HostConfig.java:1866) [catalina.jar:9.0.37] at java.util.concurrent.Executors$ RunnableAdapter.call(Executors.java:511) [na:1.8.0_331] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_331] at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) [tomcat-util.jar:9.0.37] at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112) [na:1.8.0_331] at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:1045) [catalina.jar:9.0.37] at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:429) [catalina.jar:9.0.37] at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1576) [catalina.jar:9.0.37] at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:309) [catalina.jar:9.0.37] at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) [catalina.jar:9.0.37] at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423) [catalina.jar:9.0.37] at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366) [catalina.jar:9.0.37] at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:936) [catalina.jar:9.0.37] at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:841) [catalina.jar:9.0.37] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.37] at org.apache.catalina.core.ContainerBase$ StartChild.call(ContainerBase.java:1384) [catalina.jar:9.0.37] at org.apache.catalina.core.ContainerBase$ StartChild.call(ContainerBase.java:1374) [catalina.jar:9.0.37] at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_331] at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) [tomcat-util.jar:9.0.37] at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) [na:1.8.0_331] at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909) [catalina.jar:9.0.37] at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262) [catalina.jar:9.0.37] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.37] at org.apache.catalina.core.StandardService.startInternal(StandardService.java:421) [catalina.jar:9.0.37] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.37] at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930) [catalina.jar:9.0.37] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) [catalina.jar:9.0.37] at org.apache.catalina.startup.Catalina.start(Catalina.java:738) [catalina.jar:9.0.37] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_331] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_331] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_331] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_331] at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:342) [bootstrap.jar:9.0.37] at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473) [bootstrap.jar:9.0.37] Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.GenericJDBCException: Unable to open JDBC Connection for DDL execution at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:403) ~[spring-orm-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:378) ~[spring-orm-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1858) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1795) ~[spring-beans-5.2.15.RELEASE.jar:5.2.15.RELEASE] … 58 common frames omitted Caused by: org.hibernate.exception.GenericJDBCException: Unable to open JDBC Connection for DDL execution at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:69) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcConnection(ImprovedExtractionContextImpl.java:60) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcDatabaseMetaData(ImprovedExtractionContextImpl.java:67) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.getTables(InformationExtractorJdbcDatabaseMetaDataImpl.java:333) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.getTablesInformation(DatabaseInformationImpl.java:120) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.tool.schema.internal.GroupedSchemaMigratorImpl.performTablesMigration(GroupedSchemaMigratorImpl.java:65) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:207) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:114) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:184) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:73) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.internal.SessionFactoryImpl.(SessionFactoryImpl.java:318) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:468) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.2.15.RELEASE.jar:5.2.15.RELEASE] at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:391) ~[spring-orm-5.2.15.RELEASE.jar:5.2.15.RELEASE] … 62 common frames omitted Caused by: java.sql.SQLException: null, message from server: “Host ‘WIN-IF8AUPE59UH’ is not allowed to connect to this MySQL server” at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:130) ~[mysql-connector-j-8.0.33.jar:8.0.33] at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-j-8.0.33.jar:8.0.33] at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:825) ~[mysql-connector-j-8.0.33.jar:8.0.33] at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:446) ~[mysql-connector-j-8.0.33.jar:8.0.33] at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:239) ~[mysql-connector-j-8.0.33.jar:8.0.33] at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:188) ~[mysql-connector-j-8.0.33.jar:8.0.33] at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ~[HikariCP-3.4.5.jar:na] at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:358) ~[HikariCP-3.4.5.jar:na] at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206) ~[HikariCP-3.4.5.jar:na] at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:477) ~[HikariCP-3.4.5.jar:na] at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:560) ~[HikariCP-3.4.5.jar:na] at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:115) ~[HikariCP-3.4.5.jar:na] at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[HikariCP-3.4.5.jar:na] at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:180) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:43) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final] … 77 common frames omitted 链接地址由127.0.0.1改为局域网本地ip地址,还是本机
最新发布
06-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值