文件操作--I/O

文件IO流

认识文件

我们常说的I/O,指的就是,Input/Output。那么针对硬盘持久化存储的I/O设备,当我们进行数据保存的时候,往往保存的是独立成一个个单位进行保存,而不是保存一个整体。这种独立的单位就被抽象成文件的概念。

从狭义来说,我们通常说的文件,指的是存储在硬盘上的“数据” 普通文件。

从广义来说,文件概念会广泛,操作系统会把很多的 硬件设备/软件资源,也给抽象成文件,例如,读写 网卡,网络编程,就操作系统而言会把这些硬件设备/软件资源也给抽象成文件。

抽象文件能够让系统更加的统一和管理。

文件除了有数据内容外,还有一部份的信息,such as 文件名,日期,类型,文件大小等并不作为文件的数据而存在,我们把这部分的信息称之为文件的 元信息

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TG0ns44l-1656834666134)(D:\常用文件夹\资料信息图片\Typora-image\Image\image-20220703152947359.png)

通过这一个个的文件,我们可以将这些文件给组织起来,更方便用户使用它,逻辑上也更好的理解它。

同时,随着文件越来越多,对文件的系统管理也被提上了日程,如何进行文件的组织呢,一种合乎自然
的想法出现了,就是按照层级结构进行组织 —— 也就是我们数据结构中学习过的树形结构。这样,一
种专门用来存放管理信息的特殊文件诞生了,也就是我们平时所谓文件夹(folder)或者目录(directory)的
概念。

Windows的树形结构组织:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ohdpyTlw-1656834666135)(D:\常用文件夹\资料信息图片\Typora-image\Image\image-20220703153700751.png)]

Linux上的树形结构组织:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TZ490B5A-1656834666137)(D:\常用文件夹\资料信息图片\Typora-image\Image\image-20220703153826720.png)]

文件的路径

文件路径分为两种:

1、绝对路径(以 / 开头 或者 以盘符开头):从树根出发,依次记录下中间经历的路径。

2、相对路径(以 . 或者 … 开头):从当前工作目录出发,中间经历的路径。

/ 基准所在的最顶级目录即根目录

./ 基准所在的当前目录

…/ 基准所在的当前目录的上一级目录(当前目录的父级目录)

文件的类型:

文本文件,操作文件的时候,基本单位是 “字符”

二进制文件,操作文件的时候,基本单位是“字节”

如何在java中操作文件??

1、在文件系统的层面上来操作文件

​ 创建文件、删除文件、创建目录、拷贝文件、重命名文件…

2、操作文件的内容(操作文件里面保存的数据)

​ 读文件,写文件。

在java标准库中,提供了 java.io.File 这样的类,来描述以及操作文件;(io----->input/output,输入输出)

一、File

​ 通过一个File类实例,就可以描述一个具体的文件。

  • 构造方法:
File(File parent, String child)根据父目录 + 孩子文件路径,创建一个新的 File 实例
File(String pathname)根据文件路径创建一个新的 File 实例,路径可以是绝对路径或者 相对路径
File(String parent, String child)根据父目录 + 孩子文件路径,创建一个新的 File 实例,父目录用 路径表示
  • 方法:
修饰符及返回 值类型方法签名说明
StringgetParent()返回 File 对象的父目录文件路径
StringgetName()返回 FIle 对象的纯文件名称
StringgetPath()返回 File 对象的文件路径
StringgetAbsolutePath()返回 File 对象的绝对路径
StringgetCanonicalPath()返回 File 对象的修饰过的绝对路径

重点说一下 getAbsolutePath() 和 getCanonicalPath():

1、getAbsolutePath() 表示的是绝对路径,eg:c:/././././text.txt

2、getCanonicalPath() 表示修饰过的绝对路径,此时就会对绝对路径进行修改简介,eg:C:/text.txt

看一下方法的实现:

import java.io.File;
import java.io.IOException;


public class Demo01 {
    public static void main(String[] args) throws IOException {
        File file1 =new File("d:/text.txt"); // 绝对路径
        System.out.println(file1.getParent()); 
        System.out.println(file1.getName());
        System.out.println(file1.getPath());
        System.out.println(file1.getAbsolutePath());
        System.out.println(file1.getCanonicalPath());

        System.out.println("-------------------------------------");
        File file2 = new File("./text.txt");// 有File对象,但是并不代表真实存在该文件。
        System.out.println(file2.getParent());
        System.out.println(file2.getName());
        System.out.println(file2.getPath());
        System.out.println(file2.getAbsolutePath());
        System.out.println(file2.getCanonicalPath());

    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Goxvu8dP-1656834666138)(D:\常用文件夹\资料信息图片\Typora-image\Image\image-20220627195046702.png)]

这是打印出来的结果,大家亦可以注意到,在IDEA里面我们用的是 “/” ,但是打印出来是 “\”

大部分都是使用 ”/ “ 作为目录之间的分隔符;但是对于 Windows来说 “\” 作为分隔符,这要扯就要扯到Windows的历史了…(锅是产品经理的锅🕷🕷🕷🕷🕷🕷)

所以记住结论:

  • Windows 是 “\” 作为分割符
  • Linux/Mac 大部分的操作系统都是 “/” 作为分隔符

❓❓❓❓ 为啥大部分的操作系统都是使用 “/” 分割符??

很简单,在编程语言中 “\” 表示的是转义字符亚,转义字符都是有特殊含义的,可能在编程中你非要写 “\” 那么你就得加两个“\ \” 。

booleanexists()判断 File 对象描述的文件是否真实存在
booleanisDirectory()判断 File 对象代表的文件是否是一个目录
booleanisFile()判断 File 对象代表的文件是否是一个普通文件
booleancreateNewFile()根据 File 对象,自动创建一个空文件。成功创建后返 回 true
booleandelete()根据 File 对象,删除该文件。成功删除后返回 true
String[]list()返回 File 对象代表的目录下的所有文件名
File[]listFiles()返回 File 对象代表的目录下的所有文件,以 File 对象 表示
import java.io.File;
import java.io.IOException;

public class Demo02 {
    public static void main(String[] args) throws IOException {
        File file1 = new File("./text.txt");
        System.out.println(file1.exists()); //false
        System.out.println(file1.isDirectory()); // false
        System.out.println(file1.isFile()); // false
        System.out.println("=========================");

        System.out.println(file1.createNewFile()); // 创建了一个新文件   true
        System.out.println(file1.exists()); // true
        System.out.println(file1.isDirectory()); // false
        System.out.println(file1.isFile()); //true
        System.out.println("删除文件之前");
        System.out.println(file1.delete()); // true
        System.out.println("删除文件之后");
        System.out.println(file1.exists()); // false
    }
}

注意:

1、file.createNewFile() 创建文件的操作是不一定成功的,可能会导致没有权限,创建失败,这里就需要直接抛出IOException异常了。

2、delete()也不一定轻易删除文件成功,一方面是权限,一方面是你的文件路径不对

voiddeleteOnExit()根据 File 对象,标注文件将被删除,删除动作会到 JVM 运行结束时才会进行

这个方法可以说一下,这个方法操作不是立即删除,而是等程序退出的时候再删除,这个功能一般适用于临时文件。

import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;

public class Demo04 {
    public static void main(String[] args) throws IOException, InterruptedException {
        File file1 = new File("./111.txt");
        file1.createNewFile();
        file1.deleteOnExit();

        TimeUnit.MILLISECONDS.sleep(3000);//等待3000毫秒
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-88a9oo9W-1656834666139)(D:\常用文件夹\资料信息图片\Typora-image\Image\deleteOnExit.gif)]

可以从动画中看出 deleteOnExit() 这个功能 会在程序结束的时候把临时文件删除

booleanmkdir()创建 File 对象代表的目录
booleanmkdirs()创建 File 对象代表的目录,如果必要,会创建中间目 录

创建目录,mkdir()只能创建一级目录;

mkdirs()创建多级目录 ,eg:./111/222/333/

import java.io.File;

public class Demo05 {
    public static void main(String[] args){
        File f1 = new File("./111/22/33/");
        f1.mkdirs();
        System.out.println(f1.isDirectory());
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2FdLyBI4-1656834666141)(D:\常用文件夹\资料信息图片\Typora-image\Image\image-20220628161243185.png)]

booleanrenameTo(File dest)进行文件改名,也可以视为我们平时的剪切、粘贴操 作

重命名文件。

import java.io.File;

public class Demo06 {
    public static void main(String[] args) {
        File f1 = new File("./text.txt");
        File f2 = new File("./text2.txt");
        f1.renameTo(f2);
    }
}

把文件 f1 的名字重命名为 f2 的名字。

二、字节流

2.1 InputStream (输入流)

字节流中 InputStream(负责读) / OutputStream(负责写) ,这个系列是针对二进制文件进行读写,基本单位都是字节。

主要的功能实现:

1、打开文件(构造方法)

2、读文件

3、写文件

4、关闭文件

方法:

修饰符及 返回值类 型方法签名说明
intread()读取一个字节的数据,返回 -1 代表已经完全读完了
intread(byte[] b)最多读取 b.length 字节的数据到 b 中,返回实际读到的数 量;-1 代表以及读完了
intread(byte[] b, int off, int len)最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返 回实际读到的数量;-1 代表以及读完了
voidclose()关闭字节流
2.1.1 read() 读文件
  • 读文件
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class Demo07 {
    public static void main(String[] args) {
        /**
         * InputStream 输入流,是一个抽象类,要使用需要具体实现类。
         * FileInputStream 是一个典型的实现
          */
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream("./text.txt");
            // 需要读文件,就需要字节一个一个的读出来
            while (true){
                // 为什么是 int接收 ,看一下 read()的注释
                int b = inputStream.read();
                if (b == -1){
                    break;
                }
                System.out.println(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

InputStream 抽象类起到总览全局的作用,要使用需要具体是实现类,FileInputStream就是只关心文件中的读取,所以FileInputStream就是一个典型的类实现。

签名说明
FileInputStream(File file)利用 File 构造文件输入流
FileInputStream(String name)利用文件路径构造文件输入流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-POPdrLmP-1656834666142)(D:\常用文件夹\资料信息图片\Typora-image\Image\image-20220628170423811.png)]

重点说一说 read()方法,该操作的核心方法提供了三个版本 read(byte[] b) 、read()、read(byte[] b ,int off , int len) ,现讲讲这段代码的版本。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E2yfpHtx-1656834666142)(D:\常用文件夹\资料信息图片\Typora-image\Image\image-20220628171358314.png)]

❔❔❔❔❔ 尽然是读字节 为啥不用 byte ,而用 int 尼???

进入 read()源码,用的是 int 类型接收;int 的 Range (0~255),byte 的 Range(-128~127),此处不许要参与运算,因为读出来的只是一个单纯的 字节。通过翻译一颗得知读取到文件末尾没有字节就返回 -1 ,得到 -1 就表示这个文本文件读完了。

在进行各种各样输入输出的操作中,都可能会产生异常,读文件的时候,可能读着读着就磁盘就坏了,这种时候就抛出IOException异常。

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FmKgVv4K-1656834666143)(D:\常用文件夹\资料信息图片\Typora-image\Image\image-20220628172405013.png)]

我们是以 字节流 来读,那么读出来的结果就是这些字符的 ASCII 码;如果存的是中文,读出来的中文就是每个字节的编码(GBK/UTF8),因为我的IDEA是UTF8所以读出来一个中文三个字节。

第二种写法(简单不冗长):

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class Demo08 {

    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("./text.txt")){
            while(true){
                int b = inputStream.read();
                if (b == -1){
                    break;
                }
                System.out.println(b);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

把要释放的资源放到 try()里面,然后就会自动调用到关闭,无论是否异常,这种写法 JDK1.5就有了。

前提是 try()里的对象能够实现 Closeable 接口,但是文件流对象,都是实现了 Closeable 接口的。

2.1.2 read(byte[] b) 读文件

这个方法一次读若干个字节,尽可能的填满这个字节数组,方法返回值是实际读到的字节数。

1、此处的参数 b 是一个用来表示方法返回结果的参数,称之为“输出型参数”。

2、如果文件中剩余的数据比较多,超过了参数数组的长度,就会直接返回数组长度(把数组填满)。

3、如果文件中剩余的数据比较少,不超过参数数组的长度,此时就会直接返回实际的元素个数。

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Demo09 {
    public static void main(String[] args){
        // 尝试一次性读取 1024 个字节
        try(InputStream inputStream = new FileInputStream("./text.txt")) {
            byte[] buffer = new byte[1024];
            while (true){
                // 因为实际长度 < 1024 所以返回的是实际元素个数
                int len = inputStream.read(buffer);
                if (len == -1){
                    break;
                }

                // 这个操作是把 1024个数组全部遍历打印出来
//                for (byte b: buffer){
//                    System.out.println(b);
//                }

                // 如需只打印字符串,直接转换即可
                String str = new String(buffer,0,len,"UTF-8");
                System.out.println(str);
            }
        }catch(IOException e){
            e.printStackTrace();
        }
    }
}
2.1.3 通过字符读

InputStream 这个是按照字节来读取,我们也可以通过 Reader/ FileReader 按照字符来读。

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Dome10 {
    public static void main(String[] args){
        try(FileReader fileReader = new FileReader("./text.txt")) {
            while(true){
                // 这里也是通过 int 来接收 字符
                int c = fileReader.read();
                if (c == -1){
                    break;
                }
                // 需要转换成 char 类型才行,不然就是 ascii 码值。
                System.out.println((char)c);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

总结下来:读字节,一次读的是一个 byte ,读字符,一次读的是一个 char。

2.2 OutputStream(输出流)

按照字节来写:OutputSteam / FileOutputStream。

修饰 符及 返回 值类 型方法签名说明
voidwrite(int b)写入要给字节的数据
voidwrite(byte[] b)将 b 这个字符数组中的数据全部写入 os 中
intwrite(byte[] b, int off, int len)将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个
voidclose()关闭字节流
voidflush()重要:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为 了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的 一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写 入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的 数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置, 调用 flush(刷新)操作,将数据刷到设备中

OutputStream 打开的文件就会默认清空之前这个文件。

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class Demo11 {
    public static void main(String[] args){
        try (OutputStream outputStream = new FileOutputStream("./text.txt")){
            outputStream.write(97);
            outputStream.write(98);
            outputStream.write(99);
            outputStream.flush();
        } catch (FileNotFoundException e) { // FileNotFoundException 是 IOException的子类是可以合并简化的。
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

按照字符来写:Writer / FileWriter

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class Demo12 {
    public static void main(String[] args){
        try(Writer writer = new FileWriter("./text.txt")) {
            writer.write('x');
            writer.write('x');
            writer.write('x');
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  • 总结

1、读文件,InputStream / FileInputStream / Reader / FileReader ------> read

2、写文件,OutputStream / FileOutputStream / Writer / FileWriter ------> write

三、案例实现

3.1 案例一 (删除符合条件文件)

扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件。

步骤:
1、让用户输入一个带扫描的路径;
2、判断路径是否合法;
3、输入要删除的文件;
4、遍历当前目录,遍历所有文件名和带删除文件名匹配的文件;
5、进行删除操作,把result里找到所有文件,都依次进行删除。
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class DeleteFile {
    public static void main(String[] args) throws IOException {
        // 1、先让用户输入带扫描的目录路径
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入要扫描的目录路径");
        String rootDirPath = scan.next();
        // 2、判断文件的路径合不合法
        File rootDir = new File(rootDirPath);
        if (!rootDir.isDirectory()){
            System.out.println("你扫描的目录路径不合法,请重新输入目录路径");
            return;
        }

        // 3、输入要删除的文件
        System.out.println("请输入你要删除的文件名:");
        String deleteFileName = scan.next();

        // 4、遍历当前这个目录下的文件,找到所有文件名和待删除文件匹配的文件。
        List<File> result = new ArrayList<>();
        //    通过 scanDir 这个方法, 把所有和 deleteFileName 匹配的文件, 都给找出来, 放到 result 中.
        scanDir(rootDir, deleteFileName ,result);

        // 5、进行文件的删除操作,把result 里面找到的文件,依次删除.
        for (File f:result){
            System.out.println(f.getCanonicalPath()+"该文件是否删除?Y/N");
            String choice = scan.next();
            if (choice.equals("Y")){
                f.delete();
                System.out.println(f.getCanonicalPath()+"该文件删除成功!!");
            }
        }
    }

    public static void scanDir(File rootDir ,String deleteFileName , List<File> result) throws IOException {
        // 1、首先罗列出 rootDir 目录下的文件 ----》 需要用到方法 :listFiles()
        File[] files = rootDir.listFiles();
        // 遍历,扫描所有文件
        for (File f:files) {
            System.out.println("扫描了文件:"+f.getCanonicalPath());
            // 判断是否是普通文件
            if(f.isFile()){
                // 判定文件名字
                if (f.getName().equals(deleteFileName)){
                    result.add(f);
                }
                // 文件是目录就递归
            } else if(f.isDirectory()) {
                scanDir(f,deleteFileName,result);
            }
        }
    }
}

3.2 案列二 (普通文件复制)

步骤:
1、输入需要复制的原文件以及目标文件;
2、判定 原文件是否存在;
3、进行复制操作,用到InputStream(负责读),OutputStream(负责写);
import java.io.*;
import java.util.Scanner;

public class CopyFile {
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入原文件的路径");
        String src = scan.next();
        System.out.println("请输入目标文件的路径");
        String destination = scan.next();


        // 判断 src 是否存在
        File srcFile = new File(src);
        if (!srcFile.exists()) {
            System.out.println("当前路径文件不存在,请重新输入");
            return;
        }

        // 进行复制操作,关键用到 InputStream and OutputStream
        try(InputStream inputStream = new FileInputStream(src)) {
            try(OutputStream outputStream = new FileOutputStream(destination)) {
                byte[] buffer = new byte[1024];
                while(true){
                    int len = inputStream.read(buffer);
                    if (len == -1){
                        break;
                    }
                    // 读取数据
                    outputStream.write(buffer,0,len);
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.3 案例三 (找到文件中包含指定字符)

扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)

步骤:
1、输入目录和要查找的内容;
2、进行递归遍历,找到所有符合要求的文件(这里面实际了两个方法);
3、打印找到的结果;

其实就是案例一 和 案例二 的结合。

import java.io.*;
import java.sql.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class FindContentFile {
    public static void main(String[] args) throws IOException {
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入要遍历的目录");
        String rootDirPath = scan.next();
        System.out.println("请输入要指定查找的内容");
        String content = scan.next();
        // 判断一下 目录路径是否存在
        File rootDir = new File(rootDirPath);
        if (!rootDir.exists()){
            System.out.println("您输入的路径不存在!");
            return;
        }
        // 存在进行递归遍历
        List<File> results = new ArrayList<>();
        scanDirWithContent(rootDir,content,results);

        // 打印文件结果
        for (File f:results){
            System.out.println(f.getCanonicalPath());
        }
    }

    private static void scanDirWithContent(File rootDir,String content,List<File> results){
        // 列出 rootDir 都有哪些文件
        File[] files = rootDir.listFiles();
        if (rootDir == null){
            return;
        }

        // 2. 依次遍历每个文件, 进行判定. 如果是目录就进行递归.
        for (File f:files){
            if(f.isFile()){
                // 是普通文件就进行判断 content 是否包含其中
                if (isContentExist(f,content)){
                    results.add(f);
                }
            } else if(f.isDirectory()){
                scanDirWithContent(f,content,results);
            }
        }
    }

    private static boolean isContentExist(File f, String content) {
        StringBuilder sb = new StringBuilder();
        try(Reader reader = new FileReader(f)){
            while (true){
                int c = reader.read();
                if (c == -1){
                    break;
                }
                sb.append((char) c);

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // indexOf 如果找到了子串,就返回正常的下标,没找的就返回-1;
        return sb.indexOf(content) != -1;
    }
}

注意:这段代码是低效代码,尽量不要在太复杂的目录下或者大文件下实验 。


这篇帖子介绍了文件操作以及I/O流的基本用法和基础概念,都是必掌握。

铁汁们,觉得笔者写的不错的可以点个赞哟❤🧡💛💚💙💜🤎🖤🤍💟,收藏关注呗,你们支持就是我写博客最大的动力!!!!

  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
根据您提供的Makefile,这个错误信息是由于在删除目标文件时出现问题引起的。这可能是由于您的Dev-C++环境配置不正确导致的。 在您的Makefile,您使用了`$(DEL)`变量来执行删除操作。然而,在Windows环境下,删除操作通常使用`del`命令而不是`devcpp.exe INTERNAL_DEL`。 为了解决这个问题,您可以尝试将以下行: ``` DEL = C:\Program Files (x86)\Embarcadero\Dev-Cpp\devcpp.exe INTERNAL_DEL ``` 替换为: ``` DEL = del ``` 这将使用Windows的`del`命令来执行删除操作。 修改后的Makefile如下所示: ```makefile # Project: 项目1 # Makefile created by Embarcadero Dev-C++ 6.3 CPP = g++.exe CC = gcc.exe WINDRES = windres.exe OBJ = main.o LINKOBJ = main.o LIBS = -L"C:/Program Files (x86)/Embarcadero/Dev-Cpp/TDM-GCC-64/lib" -L"C:/Program Files (x86)/Embarcadero/Dev-Cpp/TDM-GCC-64/x86_64-w64-mingw32/lib" -static-libgcc INCS = -I"C:/Program Files (x86)/Embarcadero/Dev-Cpp/TDM-GCC-64/include" -I"C:/Program Files (x86)/Embarcadero/Dev-Cpp/TDM-GCC-64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Embarcadero/Dev-Cpp/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include" CXXINCS = -I"C:/Program Files (x86)/Embarcadero/Dev-Cpp/TDM-GCC-64/include" -I"C:/Program Files (x86)/Embarcadero/Dev-Cpp/TDM-GCC-64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Embarcadero/Dev-Cpp/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include" -I"C:/Program Files (x86)/Embarcadero/Dev-Cpp/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++" BIN = 项目1.exe CXXFLAGS = $(CXXINCS) -std=c++11 CFLAGS = $(INCS) -std=c++11 DEL = del .PHONY: all all-before all-after clean clean-custom all: all-before $(BIN) all-after clean: clean-custom ${DEL} $(OBJ) $(BIN) $(BIN): $(OBJ) $(CPP) $(LINKOBJ) -o $(BIN) $(LIBS) main.o: main.cpp $(CPP) -c main.cpp -o main.o $(CXXFLAGS) ``` 请尝试使用修改后的Makefile重新编译您的项目,看看是否能够解决问题。如果还有其他错误信息,请提供详细的错误信息,以便我更好地帮助您解决问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鸢也

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值