最近项目上用到File类去创建文件夹和图片,在通过Nginx直接访问图片的时候,Nginx返回403没有访问权限的问题。
█文件权限
(1)查看文件权限
通过命令ls -l可以查看文件夹或文件的权限信息
drwxr-xr-x:
d:directory的开头字母,表示文件是一个目录。-表示文件。
rwxr-xr-x:9位标识,前三个标识表示当前文件拥有者拥有的权限,中间三个标识表示与文件拥有者所在同一个组内成员拥有的权限,最后三个标识表示其他人员拥有的权限。
r:read,读权限
w:write,写权限
x:execute,执行权限,即可以运行该文件(脚本等)
(2)更改文件权限
使用二进制表示,拥有权限用1表示,没有权限用0表示,则rwxr-xr-x可以表示为111101101。将三种用户的权限分开表示则为111 101 101,将各二进制转换成10进制为:7 5 5。
执行命令: chmod 权限值 文件,比如chmod 755 this_is_dirctory。
更详细的chmod介绍和使用,请戳《Linux chmod 命令 | 菜鸟教程》
(3)文件需要存在
当对一个不存在的文件设置权限的时候,会报错。
(4)默认权限
当创建目录或者文件的时候,操作系统会分配默认权限。默认权限可以更改。
在我使用的操作系统上,目录的默认权限为:rwxr-xr-x
文件的默认权限为:rw-r--r--
█Java创建文件并设置权限
使用File类创建文件。
package java.io;
public class File
implements Serializable, Comparable<File>
(1)代码
代码的用意是在目录/upload下创建一个this_is_directory目录,以及this_is_file文件。并且给目录this_is_directory三种用户都分配福读、写、执行权限,给文件this_is_file三种用户都分配读、执行权限。
FileOutputStream out = null;
try {
File dir = new File("/upload/this_is_directory");
if (!dir.exists() && !dir.isDirectory()) {
dir.setWritable(true, false);
dir.setReadable(true, false);
dir.setExecutable(true, false);
dir.mkdirs();
}
File file = new File("/upload/this_is_file");
file.setReadable(true, false);
file.setExecutable(true, false);
out = new FileOutputStream(file);
//out.write(content);
out.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out!=null) {
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行上述代码,当查看目录和文件权限的时候,发现并不是如预期那样,而是使用的默认权限。问题是出在生成文件和分配权限代码的顺序错误了,即
dir.setWritable(true, false);
dir.setReadable(true, false);
dir.setExecutable(true, false);
dir.mkdirs();
正确的顺序应该为:
dir.mkdirs();
dir.setWritable(true, false);
dir.setReadable(true, false);
dir.setExecutable(true, false);
这里是因为当执行setWritable、setReadable、setExecutable方法的时候,会去给文件设置权限,而此时文件还不存在,所有权限不会生效。要等文件创建成功存在了之后才能设置权限。(文件不存在设置权限失败,即上面的第(3)条)
正确的代码:
FileOutputStream out = null;
try {
File dir = new File("/upload/this_is_directory");
if (!dir.exists() && !dir.isDirectory()) {
dir.mkdirs();
// 需要等文件夹创建了之后,再去设置权限
dir.setWritable(true, false);
dir.setReadable(true, false);
dir.setExecutable(true, false);
}
File file = new File("/upload/this_is_file");
out = new FileOutputStream(file);
//out.write(content);
out.flush();
// 等文件创建之后,再设置权限
file.setReadable(true, false);
file.setExecutable(true, false);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out!=null) {
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}