轻松入门大数据:玩转Flink,打造湖仓一体架构无密分享

#1

download:轻松入门大数据:玩转Flink,打造湖仓一体架构无密分享

Java中常用的目录和文件操作,使用时可以从这里复制。
文件是操作系统在磁盘上对数据的组织。包括文件路径和文件名,例如:
/用户/Calvin/桌面/demo.txt
复制代码
文件名的后缀实际上是文件名的一部分。文件不一定要有后缀,但必须有文件路径和文件名。后缀名称只是为了某些操作系统更好的区分文件类型,从而正确操作文件。实际操作时,应用程序一般会检查文件的MIME类型,验证它属于哪个文件,而不是简单的通过后缀名称来判断。
所有文件,不管它们的扩展名是什么,都是磁盘上的一堆二进制数据。需要正确解析这些二进制数据,以便正确使用这些文件。比如PPT文件,我们也可以用文本编辑器打开,但是文本编辑器无法正确解析PPT,所以显示的是一堆乱码。
即使是压缩文件,其实也只是一个文件。它通过内部组织将多个文件的数据和目录结构信息压缩到一个文件中。
在本文中,让我们学习Java中常见的文件和目录操作。我们将编写一个Java程序。我们每解释一个操作,程序就会多一个文件操作函数。最终我们会有一个包含常用文件操作功能的程序。后续的开发任务可以直接借鉴。
Java中文件的抽象
上面我们介绍过,文件是由操作系统组织的磁盘上的数据形式。在Java传统BIO中,文件类(java.io.File)的抽象允许我们通过文件类访问系统的文件系统。使用File类提供的方法,您可以执行以下操作:

检查文件/目录是否存在。
检查文件路径是文件还是目录。
创建目录/文件
读取目录中的文件列表。
读取文件的长度。
或者重命名或移动文件。
删除文件或空目录。

下面通过几个实际例子来介绍一下如何使用File类来完成上述文件操作。需要注意的一点是,只有文件和目录元数据可以通过File类访问。如果需要读写一个文件的内容,应该使用Java IO的FileInputStream和FileOutputStream来完成。我们将在下一章介绍这一部分。
使用File类完成文件和目录操作。
和文件环境变量分隔符。
在使用File类操作文件和文件夹之前,我们先来看两个分隔符,一个叫文件路径分隔符,一个叫环境变量分隔符。之所以引入这两个分隔符,是因为它们在不同的操作系统中有不同的表示。
例如,在Windows系统中,文件路径分隔符使用反斜杠来符合"",而在Unix和Linux系统中,它使用斜杠符号" "。例如,Windows和Mac系统中的相同文件路径将表示为
Windows中的路径
c:\ Users \ Adminr \桌面\file.txt

Linux或Mac中的路径
/用户/管理员/桌面/文件. txt
复制代码
所以为了提供跨平台的兼容性,Java提供了一个静态变量File.separator作为文件路径分隔符,它会自动决定底层的什么操作系统返回正确的路径分隔符。
与文件路径分隔符类似,还有环境变量分隔符,这在Windows和Linux系统上也是不同的。在Windows上,分号“;”冒号“:”用于Linux和Mac系统。
Windows上的环境变量
c:\ Windows \ System32 \ cmd . exe;D:\Program Files\Java\jdk1.8.0
Linux上的环境变量
/usr/local/bin:/usr/bin:/bin

复制代码
所以Java也提供了File.pathSeparator静态变量来帮助我们处理不同系统上环境变量分隔符的差异。
包com . example . learn file;

导入Java . io . file;

公共类分隔符AppMain {
公共静态void main(String[] args) {
System.out.println(“文件路径分隔符:”+file . separator);
System.out.println(“环境变量分隔符:”+file . path separator);
}
}
复制代码
我们可以运行上面的例程试一试,它在Mac上会有如下输出。使用Windows的读者可以自己运行一下,看看它会不会输出Windows对应的文件路径和环境变量分隔符。
路径分隔符:/
环境变量分隔符::
复制代码
首先,我们通过编写一个简单的文件和目录操作类来说明File提供的文件和目录操作函数。
首先,我们向该类添加两个属性。
导入Java . io . file;
导入Java . io . io exception;
导入Java . util . ArrayList;
导入Java . util . arrays;
导入Java . util . list;
导入Java . util . scanner;
导入Java . util . stream . collectors;
公共类CreateDirAndFileAppMain {
公共静态最终字符串ROOT = “,”+file . separator;
私有静态扫描器scanner =新扫描器(system . in);

}
复制代码

ROOT是指我们操作所在的根目录,这里我们直接设置为“.”来表示执行java命令的目录。
Scanner是java.util.Scanner类的实例,可以以命令行交互的形式接受用户的输入,并以字符串的形式将输入逐行读入程序。具体用法见下面的例子。

创建文件实例
在Java可以对文件系统类做任何事情之前,它必须首先创建File类的一个实例。
File dir =新文件(ROOT+" File-demo/");
复制代码
File类的构造方法以文件的路径作为参数。如果参数指定文件系统上不存在的文件或目录,则构造方法不会引发异常,但通常会返回File类的实例。通过文件实例,我们可以判断文件/目录是否存在,执行文件操作等等。
创建文件夹
在知道所有的文件和目录操作都是通过file instance的方法来完成之后,我们编写第一个工具方法,用File instance来检查路径是否是目录,如果是,用File instance创建。
私有静态文件createDir(字符串…restPaths) {

string rest = joinRestDir(rest paths);
System.out.println ("+rest将在"+ROOT+“下创建);
File dir =新文件(ROOT,rest);
if(目录存在()&&目录目录()){
System.out.println(“文件夹已存在”+dir . tostring());
返回目录;
}否则{
boolean create success = dir . mkdirs();
if (createSuccess) {
返回目录;
}否则{
抛出new IllegalArgumentException(“无法在”+ROOT+”)下创建"+rest ";
}
}

}

私有静态字符串joinRestDir(字符串…restPaths) {
返回Arrays.stream(restPaths)。map(String::trim)。collect(collectors . joining(file . separator));
}
复制代码
这种方法有以下几点需要注意

File的构造方法有几个重载版本。这里使用的构造方法第一个参数是父目录,第二个参数是父目录下的子路径。这两个参数拼接在一起,形成文件实例指向的完整路径。
Dir.exists(),文件实例的exists方法可以判断实例指向的文件路径是否实际存在于文件系统中;
Dir.isDirectory(),文件实例的isDirectory方法可以确定实例指向的文件路径是否为文件夹;
Dir.mkdirs(),最后调用File实例的mkdirs()方法逐层创建文件夹。将创建不存在于整个路径上的文件夹。
在joinRestDir方法中,Lambda用于将参数数组中的各级目录组合成一个路径字符串,以文件分隔符作为分隔符。

我们从命令行用户的输入中读取CreateDir方法的参数。
私有静态文件createDirs() {
list path list = new ArrayList();
while (true) {
System.out.println(“请输入文件路径,如果为空,结束”);
string path = scanner . nextline();
if (path.isBlank()) {
打破;
}
pathList.add(路径);
}

返回create dir(path list . to array(new String[0]);
}
复制代码

Scanner.nextLine()从用户的命令行输入中读取一行,并将其作为字符串返回。

最后,该方法将用户逐层输入的目录名放入一个数组中,并将其传递给我们上面创建目录的工具方法。
重命名目录/文件
私有静态文件renameDir(文件目录){
System.out.println(“请输入新文件夹的名称:”);
string new dirname = scanner . nextline()。trim();

File newDir =新文件(dir.getParentFile()、new dirname);
boolean rename success = dir . rename to(new dir);

if(重命名成功){
System.out.println(“重命名”+newDirName+“成功”);
}否则{
System.out.println(“重命名为”+newDirName+“失败”);
返回null
}

返回newDir
}
复制代码

在重命名文件夹之前,首先我们需要创建一个新的File对象,指向新的目标文件夹。
使用源文件夹的File对象的renameTo方法,该方法接收目标文件夹对应的File实例作为参数,最后对文件夹进行重命名。

其实通过例程我们也可以看出,重命名也可以完成移动文件夹的操作,只要我们指定一个不同父目录的File对象作为renameTo的参数。同样,我们在这里演示的是重命名文件夹。如果文件实例指向一个文件,重命名和移动该文件是很自然的。
因此,使用File实例的renameTo方法,我们可以完成:

重命名/移动文件夹
重命名/移动文件

创建文件
如果文件实例所指向的文件在文件系统中不存在,可以使用它的createNewFile()方法在文件系统中创建(持久化)它。
File File = new File("/tmp/File-demo/File . txt ");
file . create new file();
复制代码
这个我们不做过多解释,直接说我们创建文件的工具和方法。
私有静态字符串createFiles(File newDir)引发IOException {
System.out.println(“请输入文件名前缀:”);
String fileName = scanner.next()。trim();

for(int I = 0;i < 20i++) {
File f =新文件(newDir,fileName + i +"。txt “);
system . out . println(” create file “+f . getname()+”:"+f . create new file());
}

返回文件名;
}
复制代码
删除文件
若要删除文件,请调用该文件的delete()方法。
File File = new File("/tmp/File-demo/File . txt ");
result = file.delete()

复制代码
delete()方法返回一个布尔值(true或false),指示删除是否成功。删除文件可能由于各种原因而失败,例如文件已打开、文件权限错误等。delete()方法也可以用来删除目录,但是只能删除不包含任何文件和子目录的空目录。
我们来看看删除文件的交互演示程序。
私有静态void deleteFiles(File newDir,String fileNameNew) {
System.out.println(“删除文件?”);
//在命令行中输入true或false只是为了删除文件。
boolean delete files = scanner . next boolean();

if(删除文件){
for(int I = 0;i < 20i++) {
File fn = new File(newDir,fileNameNew + i +"。txt ");
System.out.println(“删除文件:”+fn . Delete());
}
}
}
复制代码
上面的演示程序,通过读取命令行中的真实输入,确认用户想要删除,然后完成删除操作。
通过递归完成目录删除
File实例的delete()方法只能在目录为空时删除它。如果我们想删除包含文件和子目录的目录,在删除根目录之前,我们必须首先遍历目录并删除所有文件和子目录。
这个迭代必须递归地执行,以完成目录的删除。
公共静态布尔删除目录(文件目录){
file[]files = dir . list files();
如果(文件!= null){
for(文件文件:文件){
if(file.isDirectory()){
deleteDir(文件);
}否则{
file . delete();
}
}
}
返回dir . delete();
}
复制代码
上面的方法使用了一个还没有介绍的listFiles(),不过相信你已经猜到它的作用了。file实例的listFiles()方法可以列出File实例所指向的目录中的所有文件和子目录,然后我们遍历被删除目录中的文件,如果遇到子目录,就再次调用deleteDir方法删除子目录中的文件。最后,通过这种递归方式删除整个目录。
我们还编写了一个交互式确认功能来删除文件夹,以达到演示效果。
私有静态void removeDir(文件目录){
System.out.println(“删除文件夹?”);

boolean delete dir = scanner . next boolean();

if(删除目录){
delete dir(dir);
}
}
复制代码
执行演示程序
在介绍了File类的方法操作文件和目录的功能后,我们完成了整个演示程序,最后添加了它的Main方法,使我们能够运行这个演示程序。
导入Java . io . file;
导入Java . io . io exception;
导入Java . util . ArrayList;
导入Java . util . arrays;
导入Java . util . list;
导入Java . util . scanner;
导入Java . util . stream . collectors;

公共类CreateDirAndFileAppMain {
// TODO不同的操作系统可以更改该值。比如mac或linux可以写成~表示主目录。
公共静态最终字符串ROOT = “,”+file . separator;
私有静态扫描器scanner =新扫描器(system . in);

公共静态void main(String[] args)引发IOException{
// TODO使用File类依次创建多级文件夹、修改文件夹名称、在指定文件夹中创建文件、删除文件、删除文件夹。
file dir = create dirs();

file new dir = rename dir(dir);

string fileName = create files(new dir);

string fileName new = rename files(new dir,fileName);

deleteFiles(newDir,filename new);

remove dir(new dir);
}


}
复制代码
最后
在本文的整个研究中,我们共同完成了完整的可运行程序。