FileAttributeView出现空指针异常原因分析

问题?  

Java7新增了关于文件属性信息的一些新特性,通过java.nio.file.*包下面的类可以实现设置或者读取文件的元数据信息(比如最后修改时间,创建时间,文件大小,是否为目录等等)。尤其是UserDefinedFileAttributeView,可以用来自定义文件的元数据信息。于是在自己的mac上写了个小程序测试了下:

 1 import java.io.IOException;
 2 import java.nio.ByteBuffer;
 3 import java.nio.charset.Charset;
 4 import java.nio.file.Files;
 5 import java.nio.file.Path;
 6 import java.nio.file.Paths;
 7 import java.nio.file.attribute.UserDefinedFileAttributeView;
 8 import java.util.*;
 9
10 public class FileAttributeViewDemo {
11     private final static Charset CS = Charset.forName("UTF-8");
12
13     public Map<String, String> getAttributes(Path path) throws IOException {
14         Map<String, String> map = new HashMap<>();
15         Set<String> keys = Files.readAttributes(path, "*").keySet();
16         for (String attr : keys) {
17             map.put(attr, Files.getAttribute(path, attr).toString());
18         }
19         return map;
20     }
21
22     public Map<String, String> getUserMeta(Path path) throws IOException {
23         UserDefinedFileAttributeView view = Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);
24         List<String> metaKeys = view.list();
25         Map<String, String> map = new HashMap<>();
26         for (String metaKey : metaKeys) {
27             ByteBuffer buff = ByteBuffer.allocate(view.size(metaKey));
28             view.read(metaKey, buff);
29             buff.flip();
30             map.put(metaKey, CS.decode(buff).toString());
31         }
32         return map;
33     }
34
35     public void writeUserMeta(Path path) {
36         UserDefinedFileAttributeView view = Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);
37         try {
38             view.write("author", CS.encode("everSeeker"));
39             view.write("date", CS.encode("20160505"));
40             view.write("title", CS.encode("Effective-Java中文版.pdf"));
41             view.write("pageTotal", CS.encode("229"));
42         } catch (IOException e) {
43             e.printStackTrace();
44         }
45     }
46
47     public static void main(String[] args) throws IOException {
48         FileAttributeViewDemo demo = new FileAttributeViewDemo();
49         Path path = Paths.get("/root/xxx/Java/Effective-Java.pdf");
50         //读取文件属性信息
51         Map<String, String> attrMap = demo.getAttributes(path);
52         for (Map.Entry<String, String> entry : attrMap.entrySet()) {
53             System.out.println(entry.getKey() + " : " + entry.getValue());
54         }
55         System.out.println("--------------------------------------------------------------");
56         //写自定义文件属性
57         demo.writeUserMeta(path);
58         //读取自定义文件属性
59         Map<String, String> userMetaMap = demo.getUserMeta(path);
60         for (Map.Entry<String, String> entry : userMetaMap.entrySet()) {
61             System.out.println(entry.getKey() + " : " + entry.getValue());
62         }
63     }
64 }

整个程序分为3个部分:1、读取文件Effective-Java.pdf文件的元数据信息;2、自定义文件的元数据信息,新增作者,时间,标题,页数这4个文件属性;3、读取自定义的属性信息。

然后运行了下,就报错了。程序的第38行,view.write("author", CS.encode("everSeeker")); 报空指针错误。通过debug模式查看,发现第36行

UserDefinedFileAttributeView view = Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);

定义的view==null。这就很奇怪了,因为这行代码是jdk 8.0 API手册里面的例子。把代码发给同事在window系统上跑了下,一切正常;自己又在kali linux系统上跑了下,也能正常运行。

分析:

1、首先,通过UserDefinedFileAttributeView自定义的文件元数据信息(UserMeta)肯定是持久化了。因为调用一次writeUserMeta(Path path)方法后,重启程序,直接调用getUserMeta(Path path),还是可以获得自定义的元数据信息。所以现在的问题是,这些信息持久化到哪里去了?这个问题在Vamei的博客里面找到了答案。传送门:Linux文件系统的实现。Linux文件存储系统中的inode(索引节点)存储了文件的大小,时间戳,文件权限等信息以及文件数据块block的位置信息。通过命令stat [文件名]可以直接获得inode的相关信息。

那么,mac系统的文件存储是怎样的呢?通过命令diskutil list发现,我的OSX Yosemite 10.10.5系统的分区格式为Apple_CoreStorage。和Linux系统采取了完全不同的文件系统。所以,基本判断程序异常的原因在于操作系统的区别。

2、继续研究,发现java7之后的supportedFileAttributeViews方法可以查看本机上面支持的FileAttributeView类型。

1 public void supportedWhichViews() {
2         Path path = Paths.get("/Users/xxxx/Books/Java并发编程的艺术.pdf");
3         FileSystem fileSystem = path.getFileSystem();
4         Set<String> supportedViews = fileSystem.supportedFileAttributeViews();
5
6         for (String view : supportedViews) {
7             System.out.println(view);
8         }
9     }

运行结果为basic, owner, unix, posix;而在Linux系统上运行这段代码,结果为owner, dos, basic, posix, user, unix。可见空指针异常的原因在于在mac osx系统,Java7根本就不支持UserDefinedFileAttributeView这个类。

时间: 2024-10-18 08:46:43

FileAttributeView出现空指针异常原因分析的相关文章

Inotify数达到限制或文件空间不足的不同表现同一本质原因分析

操作系统环境: LSB Version:    :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch Distributor ID: RedHatEnterpriseServer Description:    Red Hat Enterprise Linux Serve

ListView+CheckBox两种解决方案及原因分析

最近在用ListView+CheckBox搞一个item选中的项目,我将CheckBox的focus设置为false,另我大喜的是,CheckBox竟然可以选中(窃喜中),这么简单就搞定了,因为数据量较小,也没有发现什么问题. 后来数据多了, 页面需要滑动了, 发现了一个奇怪的问题,前面明明选中了,而再次滑动回去的时候竟然变成未选中状态! 这是我刚开始写的那段错误的代码: @Override public View getView(int position, View convertView,

Socket.Server &#39;module&#39; object has no attribute &#39;fork&#39; 原因分析

Exception happened during processing of request from ('127.0.0.1', 65066)Traceback (most recent call last): File "C:\Python27\lib\SocketServer.py", line 284, in _handle_request_nobloc self.process_request(request, client_address) File "C:\P

手游产品经理初探(八)CasinoStar玩家离开原因分析

通过Delta DNA分析报告,综合我们的游戏进行思考,我总结了几条玩家流失的经验: 1.在有限的前60秒我们没有花足够的精力去吸引玩家.就是说我们要花大量的经历在玩家进入游戏的60秒的体验上(我的澳门要吸取教训).通过Delta DNA对80款游戏的统计有30%的游戏在玩家进入游戏前60秒的表现逊色.在我们的游戏中,60秒内没有给玩家足够的震撼效果,更多的互动展示.在此时间段也不能保证玩家肯定能中Bonus,从而无法体验到Bonus的乐趣. 2.付费点的过早或太过明显占玩家流失原因的70%,从

window.open浏览器弹出新窗口被拦截—原因分析和解决方案

最近在做项目的时候碰到了使用window.open被浏览器拦截的情况,在本机实验没问题,到了服务器就被拦截了,火狐有拦截提示,360浏览器拦截提示都没有,虽然在自己的环境可以对页面进行放行,但是对用户来说,不能要求用户都来通过拦截.何况当出现拦截时,很多小白根本不知道发生了啥,不知道在哪里看被拦截的页面,百思不得其解,后来查了一下,各家浏览器支持的不一样. 另外,可以发现,当window.open为用户触发事件内部或者加载时,不会被拦截,一旦将弹出代码移动到ajax或者一段异步代码内部,马上就出

ListView+CheckBox两种解决方式及原因分析

近期在用ListView+CheckBox搞一个item选中的项目,我将CheckBox的focus设置为false,另我大喜的是,CheckBox居然能够选中(窃喜中),这么简单就搞定了,由于数据量较小,也没有发现什么问题. 后来数据多了. 页面须要滑动了, 发现了一个奇怪的问题,前面明明选中了,而再次滑动回去的时候居然变成未选中状态! 这是我刚開始写的那段错误的代码: @Override public View getView(int position, View convertView,

Beforeunload打点丢失原因分析及解决方案

淘宝的鱼相在 2012 年 8 月份发表了一篇文章,里面讲述了他们通过一个月的数据采集试验,得到的结果是:如果在浏览器的本页面刷新之前发送打点请求,各浏览器都有不同程度的点击丢失情况,具体点击丢失率统计大家请看下图(数据日期为 2012 年 7 月份): 从图中可以看出,chrome,safari 这类 webkit 内核的浏览器在本页刷新之前发送打点,导致的丢失最为严重,分别为 61%,76%,而 ie8 丢失的情况最少,为7%. (具体大家可以参看此文:http://ued.taobao.c

系统上线后WCF服务最近经常死掉的原因分析总结

前言 最近系统上线完修改完各种bug之后,功能上还算是比较稳定,由于最近用户数的增加,不知为何经常出现无法登录.页面出现错误等异常,后来发现是由于WCF服务时不时的就死掉了.后来就开始分析问题.得到的初步解决方案如下: 1.在Web端调用WCF服务使用后,未释放未关闭导致新的链接无法访问 2.增加默认的连接数,系统默认的链接数比较小 3.提供同一个WCF服务的不同实例 1.在Web端调用WCF服务使用后,未释放未关闭导致新的链接无法访问 首先保证客户端每次建立的连接在使用完成后进行关闭.那么请不

系统启动失败的原因分析及解决办法

系统启动失败的原因分析及解决办法 原因分析: 可能是配置文件/etc/fstab中错误了. 查看/etc/fstab配置文件内容: [[email protected] ~]# cat /etc/fstab # # /etc/fstab # Created by anaconda on Mon Nov  7 18:40:55 2016 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See