当前位置: 首页 > news >正文

【Java文件操作】文件系统操作文件内容操作

文件系统操作

常见API

在Java中,File类是用于文件和目录路径名的抽象表示。以下是一些常见的方法:

  1. 构造方法

    • File(String pathname):根据给定的路径创建一个File对象。
    • File(String parent, String child):根据父路径和子路径创建一个File对象。
    • File(File parent, String child):根据父File对象和子路径创建一个File对象。
  2. 文件或目录的基本信息

    • boolean exists():判断文件或目录是否存在。
    • boolean isFile():判断是否为一个普通文件。
    • boolean isDirectory():判断是否为一个目录。
    • String getName():获取文件或目录的名称。
    • String getPath():获取路径名称。
    • long length():获取文件的字节长度。
  3. 文件操作

    • boolean createNewFile():创建一个新文件,如果文件已存在则返回false。
    • boolean delete():删除文件或目录。
    • boolean mkdir():创建一个新目录。
    • boolean mkdirs():创建多级目录。
    • boolean renameTo(File dest):重命名文件或目录。
  4. 文件的读写

    • File[] listFiles():列出目录中的所有文件和子目录。
    • String[] list():列出目录中的所有文件和子目录的名称。
  5. 路径操作

    • String getAbsolutePath():获取文件的绝对路径。
    • String getParent():获取文件父目录的路径。
  6. 权限和属性

    • boolean canRead():判断文件是否可读。
    • boolean canWrite():判断文件是否可写。
    • boolean canExecute():判断文件是否可执行。

这些方法为文件和目录的创建、删除、重命名及信息获取提供了方便的API。可以根据需要使用这些方法进行文件管理操作。

经典面试题

扫描指定文件目录,找到文件名包含指定字符的所有普通文件,让用户判断是否删除该文件

import java.io.File;  // 导入File类,用于处理文件和目录
import java.util.Scanner;  // 导入Scanner类,用于接收用户输入public class Example {public static void main(String[] args) {// 创建Scanner对象以接收用户输入Scanner scanner = new Scanner(System.in);System.out.println("请输入要查找的路径名:");String path = scanner.next();  // 读取用户输入的路径名File rootPath = new File(path);  // 创建File对象// 检查输入的路径是否是一个目录if (!rootPath.isDirectory()) {System.out.println("你输入的不是一个合法的路径!!!");return;  // 如果不是合法路径,结束程序}System.out.println("请输入要删除文件的关键词:");String word = scanner.next();  // 读取用户输入的关键词scanDir(rootPath, word);  // 调用scanDir方法进行目录扫描}// 递归扫描目录,查找含有特定关键词的文件private static void scanDir(File path, String word) {File[] files = path.listFiles();  // 列出当前目录下的所有文件和子目录if (files == null) {return;  // 如果没有文件,返回}// 遍历文件数组for (File file : files) {// 如果当前项是文件,则检查是否需要删除if (file.isFile()) {checkDelete(file, word);  // 调用checkDelete方法检查文件} else {// 如果当前项是目录,递归调用scanDir方法scanDir(file, word);  }}}// 检查文件名是否包含关键词,并处理删除操作private static void checkDelete(File file, String word) {// 检查文件名是否包含指定的关键词if (file.getName().contains(word)) {System.out.println(file.getName());  // 打印匹配的文件名System.out.println("是否删除该文件?");  // 提问用户是否删除Scanner scanner = new Scanner(System.in);String check = scanner.next();  // 读取用户输入的确认信息// 如果用户输入"shi",表示确认删除if (check.equals("shi")) {boolean delete = file.delete();  // 尝试删除文件if (delete) {System.out.println("删除成功!");  // 删除成功提示} else {System.out.println("删除失败!");  // 删除失败提示}} else {return;  // 如果用户不想删除,返回}} else {return;  // 如果文件名不包含关键词,返回}}
}

运行效果如下:

文件内容操作 

Read 类常见API

在Java中,Reader类是一个抽象类,主要用于读取字符流。常用的Reader子类包括FileReaderBufferedReaderInputStreamReader等。以下是一些常见的Reader类的方法:

  1. 构造方法

    • Reader():创建一个新的Reader对象(需要子类实现具体功能)。
  2. 读取字符

    • int read():读取单个字符并返回,返回-1表示流的末尾。
    • int read(char[] cbuf):将字符读入数组中,返回实际读取的字符数量,返回-1表示流的末尾。
    • int read(char[] cbuf, int off, int len):从字符输入流中读取字符并将其存储到字符数组的一个部分中,返回实际读取的字符数量。
  3. 跳过字符

    • long skip(long n):跳过字符流中的n个字符并返回实际跳过的字符数量。
  4. 查找方法

    • boolean ready():判断是否可以读取更多字符,如果可以,返回true。
  5. 关闭流

    • void close():关闭流并释放相关资源。
  6. 获取字符流信息

    • String toString():返回此Reader的字符串表示(由具体实现决定)。
  7. 读取文本行(通常用于BufferedReader):

    • String readLine():读取一行字符,返回字符串,返回null表示流的末尾。

这些方法提供了字符流的读取功能,适用于处理文本数据。如果需要处理特定类型的输入或文件,通常会选择相应的子类,例如使用FileReader读取文件,使用BufferedReader提高读取效率等。

Writer 类常见API

在Java中,Writer类是一个抽象类,用于写入字符流。常用的Writer子类包括FileWriterBufferedWriterPrintWriter等。以下是一些常见的Writer类的方法:

  1. 构造方法

    • Writer():创建一个新的Writer对象(需要子类实现具体功能)。
  2. 写入字符

    • void write(int c):写入单个字符。
    • void write(char[] cbuf):将字符数组的内容写入流中。
    • void write(String str):将字符串的内容写入流中。
    • void write(String str, int off, int len):写入字符串的一部分,从指定的偏移量开始,最多写入指定的字符数。
  3. 缓冲

    • void flush():刷新该流,确保所有缓存的字符都被写入目标流中。
  4. 关闭流

    • void close():关闭流并释放与之关联的所有资源。
  5. 写入字符数组

    • void write(char[] cbuf, int off, int len):将数组中指定范围内的字符写入流中。
  6. 换行方法(通常用于BufferedWriter):

    • void newLine():写入一个行分隔符,通常用于文本文件的换行。
  7. 格式化输出(通常用于PrintWriter):

    • void printf(String format, Object... args):按照给定的格式输出。
    • void println():写入一个行分隔符(换行)。

这些方法提供了字符流的写入功能,非常适合处理文本文件和输出。不同的Writer实现提供了不同的功能,例如BufferedWriter提供缓存功能以提高效率,而PrintWriter则提供方便的格式化输出功能。根据具体需求,可以选择适当的Writer实现。

经典面试题

将一个文件中的内容完整复制到另一个文件中

题目描述: 请编写一个Java程序,使用ReaderWriter类,将一个文本文件中的内容复制到另一个文本文件中。请考虑使用合适的子类以提高程序的效率,并确保在读取和写入时处理异常。程序需具备以下功能:

  1. 从源文件中读取内容。
  2. 将读取的内容写入目标文件。
  3. 需要在控制台提示用户输入源文件路径和目标文件路径。
  4. 在文件操作完成后,提示用户操作结果(如复制成功、失败等)。

示例代码

下面是一个简单的实现示例:

import java.io.*;public class FileCopyExample {public static void main(String[] args) {// 使用Scanner获取用户输入的文件路径try (Scanner scanner = new Scanner(System.in)) {System.out.println("请输入源文件路径:");String sourcePath = scanner.nextLine(); // 读取源文件路径System.out.println("请输入目标文件路径:");String destPath = scanner.nextLine(); // 读取目标文件路径// 创建文件Reader和Writer对象try (Reader reader = new FileReader(sourcePath);Writer writer = new FileWriter(destPath)) {char[] buffer = new char[1024]; // 创建缓冲区int length;// 循环读取源文件内容,并写入目标文件while ((length = reader.read(buffer)) != -1) {writer.write(buffer, 0, length); // 写入缓冲区中的内容}System.out.println("文件复制成功!"); // 提示成功消息} catch (IOException e) {System.out.println("文件操作失败:" + e.getMessage()); // 提示错误消息}}}
}

注意事项

  1. 确保输入的文件路径是有效的,并且有权限读取源文件和写入目标文件。
  2. 处理可能出现的异常,如文件未找到或无法读取/写入的情况。
  3. 在实际应用中,可以使用BufferedReaderBufferedWriter进行更高效的读取和写入操作。

扩展

  • 可以考虑添加更多的功能,例如在复制前检查目标文件是否存在,是否覆盖等。
  • 可以扩展为一个方法,接收源文件和目标文件的路径作为参数,以便复用。

OutputStream 类的常见API 

在Java中,OutputStream类是一个抽象类,主要用于输出字节流。常用的OutputStream子类包括FileOutputStreamBufferedOutputStreamDataOutputStream等。以下是一些常见的OutputStream类的方法:

  1. 构造方法

    • OutputStream():创建一个新的OutputStream对象(需要子类实现具体功能)。
  2. 写入字节

    • void write(int b):将指定的字节写入输出流。参数b可以是一个字节的值(0-255)。
    • void write(byte[] b):将字节数组中的所有字节写入输出流。
    • void write(byte[] b, int off, int len):将字节数组中从off(偏移量)开始的len(长度)个字节写入输出流。
  3. 刷新

    • void flush():刷新输出流,确保所有缓冲的输出字节被写入目标流。
  4. 关闭流

    • void close():关闭输出流并释放与之关联的所有资源。
  5. 使用辅助功能(如在BufferedOutputStream中):

    • void write(byte[] b, int off, int len):也可以用于写入指定的字节数组部分。

示例代码

以下是一个简单示例,演示如何使用FileOutputStream写入字节到文件中:

import java.io.FileOutputStream;
import java.io.IOException;public class OutputStreamExample {public static void main(String[] args) {// 使用FileOutputStream写入文件try (FileOutputStream fos = new FileOutputStream("output.txt")) {String content = "Hello, World!";fos.write(content.getBytes()); // 将字符串转换为字节并写入文件fos.flush(); // 刷新流,确保所有数据都被写入System.out.println("写入成功!"); // 提示消息} catch (IOException e) {System.out.println("写入失败:" + e.getMessage()); // 错误处理}}
}

通过使用OutputStream及其子类,可以方便地进行字节数据的输出操作,主要用于文件、网络等数据流的处理。

InputStream 类的常见API

在Java中,InputStream类是一个抽象类,主要用于输入字节流。常用的InputStream子类包括FileInputStreamBufferedInputStreamByteArrayInputStream等。以下是一些常见的InputStream类的方法:

  1. 构造方法

    • InputStream():创建一个新的InputStream对象(需要子类实现具体功能)。
  2. 读取字节

    • int read():从输入流中读取下一个字节的数据,并返回(0-255)。如果到达流末尾,则返回-1。
    • int read(byte[] b):从输入流中读取数量最多为b.length字节的数据到一个字节数组中,返回实际读取的字节数,返回-1表示到达流末尾。
    • int read(byte[] b, int off, int len):从输入流中读取最多len字节的数据到字节数组b的指定偏移量off中,返回实际读取的字节数,返回-1表示到达流末尾。
  3. 跳过字节

    • long skip(long n):跳过并丢弃n个字节,从输入流中返回实际跳过的字节数。
  4. 可用字节

    • int available():返回可以从输入流中读取的字节数,而不需要阻塞。
  5. 关闭流

    • void close():关闭输入流并释放与之关联的所有资源。
  6. 标记和重置

    • void mark(int readlimit):标记当前输入流的位置,以便在读取数据后可以调用reset()方法返回到这个位置。
    • void reset():重置输入流到最后标记的位置。
    • boolean markSupported():检查该输入流是否支持标记和重置功能。

示例代码

以下是一个简单示例,演示如何使用FileInputStream读取文件内容:

import java.io.FileInputStream;
import java.io.IOException;public class InputStreamExample {public static void main(String[] args) {// 使用FileInputStream读取文件try (FileInputStream fis = new FileInputStream("input.txt")) {int byteData;// 逐个字节读取文件内容while ((byteData = fis.read()) != -1) {System.out.print((char) byteData); // 将字节转换为字符并输出}} catch (IOException e) {System.out.println("读取失败:" + e.getMessage()); // 错误处理}}
}

通过使用InputStream及其子类,可以方便地进行字节数据的输入操作,主要用于文件、网络等数据流的处理。

InputStream & OutputStream 的格式化使用

InputStream

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;public class InputStreamExample {public static void main(String[] args) {try (InputStream inputStream = new FileInputStream("./test.txt")) {Scanner scanner = new Scanner(inputStream);String s = scanner.next();System.out.println(s);} catch (IOException e) {e.printStackTrace();}}
}

OutputStream

import java.io.*;public class OutputStreamExample {public static void main(String[] args) {try (OutputStream outputStream = new FileOutputStream("./test.txt")) {PrintWriter printWriter = new PrintWriter(outputStream);printWriter.println(2);printWriter.flush();} catch (IOException e) {e.printStackTrace();}}
}

相关文章:

【Java文件操作】文件系统操作文件内容操作

文件系统操作 常见API 在Java中,File类是用于文件和目录路径名的抽象表示。以下是一些常见的方法: 构造方法: File(String pathname):根据给定的路径创建一个File对象。File(String parent, String child):根据父路径…...

关于若依flowable的安装

有个项目要使用工作流功能,在网上看了flowable的各种资料,最后选择用若依RuoYi-Vue-Flowable这个项目来迁移整合。 一、下载项目代码: 官方项目地址:https://gitee.com/shenzhanwang/Ruoyi-flowable/ 二、新建数据库&#xff…...

猜数字困难版(1-10000)

小游戏&#xff0c;通过提示每次猜高或猜低以及每次猜中的位数&#xff0c;10次内猜中1-10000的一个数。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthde…...

ASPICE术语表

术语来源描述活动Automotive SPICE V4.0由利益相关方或参与方执行的任务用参数Automotive SPICE V4.0应用参数是包含了在系统或软件层级可被更改的数据的软件变量&#xff0c;他们影响系统或软件的行为和属性。应用参数的概念有两种表达方式:规范(分别包括变量名称、值域范围、…...

Knife4j:打造优雅的SpringBoot API文档

1. 为什么需要API文档&#xff1f; 在现代软件开发中,API文档的重要性不言而喻。一份清晰、准确、易于理解的API文档不仅能够提高开发效率,还能降低前后端沟通成本。今天,我们要介绍的Knife4j正是这样一款强大的API文档生成工具,它专为Spring Boot项目量身打造,让API文档的生成…...

数学建模笔记—— 多目标规划

数学建模笔记—— 多目标规划 多目标规划1. 模型原理1.1 多目标规划的一般形式1.2 多目标规划的解1.3 多目标规划的求解 2. 典型例题3. matlab代码实现 多目标规划 多目标规划是数学规划的一个分支。研究多于一个的目标函数在给定区域上的最优化。又称多目标最优化。通常记为 …...

【鸿蒙HarmonyOS NEXT】页面之间相互传递参数

【鸿蒙HarmonyOS NEXT】页面之间相互传递参数 一、环境说明二、页面之间相互传参 一、环境说明 DevEco Studio 版本&#xff1a; API版本&#xff1a;以12为主 二、页面之间相互传参 说明&#xff1a; 页面间的导航可以通过页面路由router模块来实现。页面路由模块根据页…...

SonicWall SSL VPN曝出高危漏洞,可能导致防火墙崩溃

近日&#xff0c;有黑客利用 SonicWall SonicOS 防火墙设备中的一个关键安全漏洞入侵受害者的网络。 这个不当访问控制漏洞被追踪为 CVE-2024-40766&#xff0c;影响到第 5 代、第 6 代和第 7 代防火墙。SonicWall于8月22日对其进行了修补&#xff0c;并警告称其只影响防火墙的…...

关于SAP标准委外(带料外协)采购订单信息

业务背景&#xff1a; 业务部门提出需要将售料外协方式变更为带料外协&#xff0c;带料外协实际业务存在一个委外订单存在多次发料&#xff0c;且每次发票需要进行齐套发料&#xff0c;不同批次的发料涉及物料替代。在半成品收货时需要进行对发料的组件进行扣料。 需求分析&a…...

SpringBoot整合WebSocket实现消息推送或聊天功能示例

最近在做一个功能&#xff0c;就是需要实时给用户推送消息&#xff0c;所以就需要用到 websocket springboot 接入 websocket 非常简单&#xff0c;只需要下面几个配置即可 pom 文件 <!-- spring-boot-web启动器 --><dependency><groupId>org.springframewo…...

使用 QEMU 模拟器运行 FreeRTOS 实时操作系统

文章目录 QEMU 官网QEMU 文档QEMU 简介QEMU 安装QEMU 命令启动虚拟机串口控制台监控命令行 FreeRTOS安装编译工具FreeRTOS 源码RISC-V-Qemu-virt_GCC 示例编译 RISC-V-Qemu-virt_GCC启动虚拟机运行 FreeRTOS QEMU 官网 https://www.qemu.org/ QEMU 文档 https://www.qemu.or…...

Oracle EBS中AR模块的财务流程概览

应收账款 (AR) 模块是Oracle E-Business Suite (EBS) 中另一个重要的财务管理模块&#xff0c;主要用于管理企业销售过程中的账款回收。下面是AR模块中的一些关键财务流程及其详细说明&#xff1a; 1. 销售订单管理 创建销售订单&#xff1a;当客户下单时&#xff0c;销售人员…...

Minitab 的直方图结果分析解释

Minitab 的直方图结果分析解释 步骤 1&#xff1a;评估关键特征 检查分布的尖峰和散布。评估样本数量对直方图外观的影响。 标识尖峰&#xff08;即&#xff0c;条的最高聚类&#xff09;&#xff1a; 尖峰表示样本中最常见的值。评估样本的散布以了解数据的变异程度。例如…...

AgentRE:用智能体框架提升知识图谱构建效果,重点是开源!

发布时间&#xff1a;2024 年 09 月 13 日 Agent应用 AgentRE: An Agent-Based Framework for Navigating Complex Information Landscapes in Relation Extraction 在复杂场景中&#xff0c;关系抽取 (RE) 因关系类型多样和实体间关系模糊而挑战重重&#xff0c;影响了传统 “…...

力扣题解2390

大家好&#xff0c;欢迎来到无限大的频道。 今日继续给大家带来力扣题解。 题目描述​&#xff08;中等&#xff09;&#xff1a; 从字符串中移除星号 给你一个包含若干星号 * 的字符串 s 。 在一步操作中&#xff0c;你可以&#xff1a; 选中 s 中的一个星号。 移除星号…...

用Python获取PDF页面的大小、方向和旋转角度

在文档管理和自动化领域&#xff0c;了解PDF文档的内在属性&#xff08;如页面大小、方向和旋转角度&#xff09;对于确保一致的文档处理和布局保真度至关重要。这些属性在内容重用、归档以及PDF无缝集成到网络环境或其他数字工作流程中起着关键作用&#xff0c;因为它们直接影…...

【即时通讯】轮询方式实现

技术栈 LayUI、jQuery实现前端效果。django4.2、django-ninja实现后端接口。 代码仓 - 后端 代码仓 - 前端 实现功能 首次访问页面并发送消息时需要设置昵称发送内容为空时要提示用户不能发送空消息前端定时获取消息&#xff0c;然后展示在页面上。 效果展示 首次发送需要…...

Flock 明牌空投教程

FLock 旨在为人工智能构建一个去中心化的隐私保护解决方案。FLock提出了一项名为联合学习区块&#xff08;简称 FLocks&#xff09;的研究计划&#xff0c;该计划使用区块链作为数据持有者之间的协调平台来进行机器学习&#xff0c;同时数据保持本地和隐私。通过用区块链取代收…...

项目内部调用的远程接口开发

编写一个项目内部调用的远程接口通常是为了在分布式系统或者微服务架构中&#xff0c;实现各个服务之间的通信和数据交换。这样的远程接口专门用于服务之间的调用&#xff0c;而不是直接暴露给外部用户或前端。 项目内部的远程接口统一放在api工程 首先进入api编写接口&#x…...

影响IP代理池稳定性的因素有哪些?

IP代理池在提供网络服务时&#xff0c;稳定性是一项决定性指标。多个外部和内部因素可能会影响这个稳定性&#xff0c;因此深入理解这些影响因素&#xff0c;可以帮助优化IP代理池的性能与服务质量。 1. IP来源质量 纯净度与使用频次&#xff1a;优质的IP来源常常被描述为纯净…...

5分钟免费制作专业AI翻唱:AICoverGen完整指南

5分钟免费制作专业AI翻唱&#xff1a;AICoverGen完整指南 【免费下载链接】AICoverGen A WebUI to create song covers with any RVC v2 trained AI voice from YouTube videos or audio files. 项目地址: https://gitcode.com/gh_mirrors/ai/AICoverGen 想让AI帮你翻唱…...

CFD工程师必看:TVD格式选型指南——从SUPERBEE到UMIST,哪个才是你的菜?

CFD工程师必看&#xff1a;TVD格式选型实战指南——从工程场景到最优解 在计算流体力学(CFD)的世界里&#xff0c;TVD格式就像赛车手的轮胎选择——没有绝对的好坏&#xff0c;只有场景的适配。当你在汽车外气动分析中遇到激波振荡&#xff0c;或在燃烧模拟中面临虚假扩散时&am…...

构建高质量Awesome教程库:从Claude Code实战到开发者知识体系搭建

1. 项目概述&#xff1a;一个为Claude Code打造的开发者知识库 最近在GitHub上看到一个挺有意思的项目&#xff0c;叫“awesome-claudcode-tutorial”。光看名字&#xff0c;你可能会有点懵——“Claude Code”是什么&#xff1f;这其实是一个由开发者社区推动的、围绕特定AI编…...

OpenClaw量化回测性能调优指南:从数据加载到并行计算的实战优化

1. 项目概述&#xff1a;从开源工具到性能调优的艺术最近在跟几个做量化交易的朋友聊天&#xff0c;他们都在为一个问题头疼&#xff1a;策略回测和实盘执行的速度。动辄几十个G的历史数据&#xff0c;复杂的因子计算&#xff0c;加上高频的模拟交易&#xff0c;一套流程跑下来…...

3步玩转APK下载:开源APKMirror客户端的终极实战指南

3步玩转APK下载&#xff1a;开源APKMirror客户端的终极实战指南 【免费下载链接】APKMirror 项目地址: https://gitcode.com/gh_mirrors/ap/APKMirror 你是否曾因官方应用商店找不到某个历史版本而苦恼&#xff1f;是否担心第三方下载站点的安全性&#xff1f;今天&…...

英雄联盟智能助手Seraphine:免费开源的战绩查询与BP辅助神器

英雄联盟智能助手Seraphine&#xff1a;免费开源的战绩查询与BP辅助神器 【免费下载链接】Seraphine 英雄联盟战绩查询工具 项目地址: https://gitcode.com/gh_mirrors/se/Seraphine 还在为错过对局接受而懊恼吗&#xff1f;还在BP阶段犹豫不决错失最佳英雄选择吗&#…...

PyWxDump:微信数据管理的终极本地解决方案指南

PyWxDump&#xff1a;微信数据管理的终极本地解决方案指南 【免费下载链接】PyWxDump 删库 项目地址: https://gitcode.com/GitHub_Trending/py/PyWxDump 在数字时代&#xff0c;微信聊天记录承载着我们珍贵的回忆和重要信息&#xff0c;但你是否曾担心数据安全、备份困…...

2026届最火的降AI率神器解析与推荐

Ai论文网站排名&#xff08;开题报告、文献综述、降aigc率、降重综合对比&#xff09; TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 人工智能生成内容逐渐普及起来&#xff0c;信息质量以及真实性面临到严峻挑战。各类平台加之…...

Workerman-todpole 部署实战:Linux/Windows 环境配置与优化技巧 [特殊字符]

Workerman-todpole 部署实战&#xff1a;Linux/Windows 环境配置与优化技巧 &#x1f680; 【免费下载链接】workerman-todpole HTML5WebSocketPHP(Workerman) , rumpetroll server writen using php 项目地址: https://gitcode.com/gh_mirrors/wo/workerman-todpole Wo…...

CommonJS、RequireJS 与 ES6 模块:JavaScript 模块化演进史

JavaScript 诞生之初并没有模块化机制。随着应用规模扩大,全局变量冲突、依赖管理混乱等问题日益突出。社区和标准组织先后推出了多种模块化方案,其中最著名的是 CommonJS(主要用于服务器端)、AMD / RequireJS(主要用于浏览器端)以及 ES6 Module(官方标准)。 CommonJS、…...