如今,大量的应用程序创建文件或目录的目的非常广泛。 无论是生成报告,导出配置文件还是仅存储一些数据,能够处理这些任务都非常重要。 创建文件和目录是使用文件系统时最常用的功能之一。 图书馆的这一部分进行了相当现代化。 这方面的更新包括保证某些操作的原子性,使用预设文件属性创建文件和目录,性能优化以及引入异常层次结构,这些层次结构取代了IO库先前版本中的boolean
返回方法。
检查方法
在深入探讨任何代码或解释之前,让我退后一步,集中讨论一些不仅对本帖子至关重要,而且对以后的帖子也很重要的事情。 我发现熟悉一些通常称为检查方法的方法很重要。 检查方法包括所有用于在调用实际文件系统操作代码之前执行各种检查的方法。 为了方便起见,它们都在类java.nio.file.Files
。 使用这些方法将帮助您防止应用程序发生意外行为。 由于这些方法非常简单,因此我将跳过专用于它们的示例,而在以后的示例中使用它们。
方法名称 | 描述 |
---|---|
exists(Path path, LinkOption... options) | 测试文件是否存在。 |
isExecutable(Path path) | 测试文件是否可执行。 |
isHidden(Path path) | 告诉文件是否被视为隐藏文件。 |
isReadable(Path path) | 测试文件是否可读。 |
isRegularFile(Path path, LinkOption... options) | 测试文件是否是具有不透明内容的常规文件。 |
isSameFile(Path path, Path path2) | 测试两个路径是否找到同一文件。 |
isWritable(Path path) | 测试文件是否可写。 |
notExists(Path path, LinkOption... options) | 测试通过此路径定位的文件是否不存在。 |
创建一个新目录
类Files
的最重要用途之一是使用createDirectory
方法创建新目录。 目录创建是非常简单和直接的过程,因此无需太多解释。 像往常一样,它总是使用检查方法是个好主意exists
的类Files
,以确保它可以创建与给定路径的目录,同时防止FileAlreadyExistsException
。 下列代码段展示了整个情况:
Path newDirectoryPath = Paths.get("/home/jstas/directory");if (!Files.exists(newDirectoryPath)) {try {Files.createDirectory(newDirectoryPath);} catch (IOException e) {System.err.println(e);}
}
该代码示例非常简单–在没有其他文件系统条目驻留在提供的路径上的情况下,它使用提供的路径创建目录。 如果需要创建整个目录层次结构,则需要切换到createDirectories
方法,该方法的行为类似,并创建由路径实例定义的整个层次结构。 由于目录是文件的一种,因此我们可以设置其自己的元数据( 文件属性 )。 我们不仅能够做到这一点,甚至可以预先创建元数据定义,并在原子操作中创建具有初始文件属性的目录,以防止沿途出现任何不一致之处。 如前一篇文章所述,管理文件系统权限有两种受支持的标准:POSIX和ACL。
POSIX文件权限
首先,让我们看一下如何在与POSIX兼容的系统(如基于Linux的系统和Mac OS)上管理文件系统权限。 由于POSIX文件权限非常容易理解,库创建者为我们提供了便捷的工具,例如从字符串表示形式直接转换为一组PosixFilePermission
或将其转换为FileAttribute
对象的转换工具。 这不是创建FileAttribute
对象的唯一方法,我们将在下一章中看到。
回到前面的示例,让我们看下面的代码。 使用PosixFilePermissions
类的便捷方法fromString
,我们可以创建一组PosixFilePermission
。 现在,需要创建FileAttribute
实例,该实例将传递给createDirectory
测试目录的createDirectory
方法。 让我们看下面的代码片段:
Path newDirectoryPath = Paths.get("/home/jstas/testPosix");if (!Files.exists(newDirectoryPath)) {Set<PosixFilePermission> permissions = PosixFilePermissions.fromString("r-xr-----");FileAttribute<Set<PosixFilePermission>> fileAttributes = PosixFilePermissions.asFileAttribute(permissions);try {Files.createDirectory(newDirectoryPath, fileAttributes);} catch (IOException e) {System.err.println(e);}
}
很容易验证我们的权限设置是否正确。 您可以直接从Java代码读取文件属性,如我在文件属性文章中介绍的那样,也可以手动执行。 我使用系统终端通过以下输出检查它们:
dr-xr-----. 2 jstas jstas 4096 Jan 5 13:34 testPosix
ACL文件权限
在ACL兼容系统(例如Windows(NT,2000,XP和更高版本))上管理文件系统权限时,事情变得有些复杂。 ACL列表会变得非常复杂和健壮,因此这里没有POSIX文件权限之类的快捷方式。 此处的关键是使用基于接口FileAttribute
的匿名类定义。 该接口仅定义两种方法: name
返回文件属性的名称, value
返回此属性的值。 使用ACL时,我们感兴趣的属性名称为'acl:acl' 。 value
方法仅返回构造的ACL条目的列表。
让我们看一下ACL条目内隐藏的内容以及如何创建AclEntry
实例。 首先,ACL条目包含几个对象:
- 标志
- 标志组件是一组标志,用于指示条目如何被继承和传播
- 权限
- 权限组件是一组权限
- 类型
- 类型组件确定该条目是授予还是拒绝访问。
- 主要
- 主体组件(有时称为“谁”组件)是与条目授予或拒绝访问的身份相对应的
UserPrincipal
- 主体组件(有时称为“谁”组件)是与条目授予或拒绝访问的身份相对应的
考虑到单个ACL条目的复杂性,NIO.2库的创建者看到了一个非常合适的实现构建器模式的候选人。 请访问以下页面,以获取有关设计模式和构建器模式的更多信息。 因此,实现选择适当的标志和权限,将其与用户主体绑定,并设置条目的类型。 请研究以下代码片段以熟悉ACL权限:
Path newDirectoryPath = Paths.get("c:", "testACL");if (!Files.exists(newDirectoryPath)) {FileAttribute<List<AclEntry>> fileAttributes = new FileAttribute<List<AclEntry>>() {@Overridepublic List<AclEntry> value() {// lookup user principalFileSystem fileSystem = FileSystems.getDefault();UserPrincipalLookupService userPrincipalLookupService = fileSystem.getUserPrincipalLookupService();UserPrincipal userPrincipal = null;try {userPrincipal = userPrincipalLookupService.lookupPrincipalByName("JStas");} catch (IOException e) {throw new RuntimeException(e);}// select ACL flagsSet<AclEntryFlag> flags = EnumSet.of(AclEntryFlag.FILE_INHERIT, AclEntryFlag.DIRECTORY_INHERIT);// select ACL permissionSet<AclEntryPermission> permissions = EnumSet.of(AclEntryPermission.READ_DATA, AclEntryPermission.WRITE_DATA, AclEntryPermission.EXECUTE);// build ACL entryBuilder builder = AclEntry.newBuilder();builder.setFlags(flags);builder.setPermissions(permissions);builder.setPrincipal(userPrincipal);builder.setType(AclEntryType.DENY);AclEntry entry = builder.build();List<AclEntry> aclEntryList = new ArrayList<>();aclEntryList.add(entry);return aclEntryList;}@Overridepublic String name() {return "acl:acl";}};try {Files.createDirectory(newDirectoryPath, fileAttributes);} catch (IOException e) {System.err.println(e);}
}
要验证在Windows 7中成功创建目录及其文件属性,请在给定文件夹的属性中选择“安全性”选项卡,然后单击“高级”。 您新创建的条目应在呈现的表中列出,并具有类似于此条目的详细信息视图:
创建一个新文件
任何与文件系统相关的代码的核心部分通常都包含创建单个或多个文件的代码。 要创建文件,我们需要再次使用Files
类,并调用createFile
方法。 就像目录一样,可以使用初始文件属性创建文件,并且应用相同的限制。 话虽如此,我将不演示文件属性的工作,因为它与目录示例中的相同。 再一次,这是一个非常简单的方法,没有什么用处,因此下面的示例将介绍所有内容:
Path newFilePath = Paths.get("C:", "a.txt");if (!Files.exists(newFilePath)) {try {Files.createFile(newFilePath);} catch (IOException e) {System.err.println(e);}
}
请注意, exists
检查方法可以防止FileAlreadyExistsException
。
翻译自: https://www.javacodegeeks.com/2014/06/creating-files-and-directories-in-nio-2.html