file.lastModified()永远不会是用file.setLastModified()设置的

Har*_*elm 11 java android date milliseconds

我确实遇到了毫安设置的问题,并在Nexus One上的Android 2.3.4上阅读.这是代码:

File fileFolder = new File(Environment.getExternalStorageDirectory(), appName + "/"
    + URLDecoder.decode(folder.getUrl()));
if (fileFolder != null && !fileFolder.exists()) {
  fileFolder.setLastModified(1310198774);
  fileFolder.mkdirs();
  fileFolder.setLastModified(1310198774);
}

if (fileFolder != null && fileFolder.exists()) {
  long l = fileFolder.lastModified();
}
Run Code Online (Sandbox Code Playgroud)

在这个小测试中,我写了1310198774,但是从lastModified()返回的结果是1310199771000.

即使我削减了尾随的"000",也会有几分钟的差异.

我需要在webservice和Android设备之间同步文件.lastmodification millis是此服务发送的数据的一部分.我将millis设置为创建/复制的文件和文件夹,以检查是否需要覆盖文件/文件夹.

一切正常但是从文件系统返回的毫秒与设置的值不同.

我很确定我的代码有问题 - 但我找不到它.

提前谢谢了.HJW

Gra*_*ray 6

所以也许我错过了一些东西,但我发现上面的代码存在一些问题.您的具体问题可能是(因为@JB提到)Android问题,但对于后代,我想我会提供答案.

首先,File.setLastModified()花费时间以毫秒为单位.这是javadocs.你似乎试图在几秒钟内设置它.所以你的代码应该是这样的:

fileFolder.setLastModified(1310198774000L);
Run Code Online (Sandbox Code Playgroud)

正如javadocs中提到的,许多文件系统仅支持最后修改时间的秒粒度.因此,如果您需要在文件中看到相同的修改时间,那么您应该执行以下操作:

private void changeModificationFile(File file, long time) {
    // round the value down to the nearest second
    file.setLastModified((time / 1000) * 1000);
}
Run Code Online (Sandbox Code Playgroud)


ce4*_*ce4 5

在Jelly Bean +上,它是不同的(主要是在Nexus设备上,还有其他使用新的保险丝层进行/ mnt/shell /模拟sdcard仿真):

这是一个VFS权限问题,由于权限不当(例如所有权),系统调用utimensat()因EPERM而失败.

在platform/system/core/sdcard/sdcard.c中:

/*root.sdcard*/
attr-> uid = 0 拥有的所有文件;
attr-> gid = AID_SDCARD_RW;

从utimensat()的系统调用手册页:

2. the caller's effective user ID must match the owner of the file; or  
3. the caller must have appropriate privileges.  

To make any change other than setting both timestamps to the current time  
(i.e., times is not NULL, and both tv_nsec fields are not UTIME_NOW and both  
tv_nsec fields are not UTIME_OMIT), either condition 2 or 3 above must apply.  
Run Code Online (Sandbox Code Playgroud)

旧FAT通过挂载选项提供iattr-> valid标志的覆盖,允许更改任何人的时间戳,FUSE + Android的sdcard-FUSE此刻不执行此操作(因此'inode_change_ok()调用失败)和尝试被-EPERM拒绝.这是FAT的./fs/fat/file.c:

/* Check for setting the inode time. */  
ia_valid = attr->ia_valid;  
if (ia_valid & TIMES_SET_FLAGS) {  
    if (fat_allow_set_time(sbi, inode))  
        attr->ia_valid &= ~TIMES_SET_FLAGS;  
}  

error = inode_change_ok(inode, attr);
Run Code Online (Sandbox Code Playgroud)

我还将此信息添加到此漏洞中.


arn*_*ans 5

如果这一切都无效,请尝试从https://code.google.com/p/android/issues/detail?id=18624引用此(丑陋)变通方法:

//As a workaround, this ugly hack will set the last modified date to now:      
RandomAccessFile raf = new RandomAccessFile(file, "rw");
long length = raf.length();
raf.setLength(length + 1);
raf.setLength(length);
raf.close();
Run Code Online (Sandbox Code Playgroud)