谷歌文档API“setMd5C​​hecksum”不工作

问题描述:

最近我已经实现在Java使用该Google Docs API v3.0的应用程序。创建这样的新条目:谷歌文档API“setMd5C​​hecksum”不工作

DocumentListEntry newEntry = new DocumentListEntry(); 
newEntry.setFile(file, Common.resolveMimeType(file)); //Common is a custom class 
newEntry.setFilename(entryTitle.getPlainText()); //entryTitle is a TextConstruct 
newEntry.setTitle(entryTitle); 
newEntry.setDraft(false); 
newEntry.setHidden(file.isHidden()); 
newEntry.setMd5Checksum(Common.getMD5HexDigest(file)); 

相信我,当我告诉你,Common.getMD5HexDigest(file)返回一个有效且唯一的MD5哈希值十六进制。

现在,在检索文件并通过entry.getMd5Checksum()方法检查MD5校验和时,文件上传得当,它始终返回null

我用尽了一切办法,甚至成立了ETagResourceIDVersionID但是大家都能用默认值(null或服务器生成的字符串)覆盖。

+0

很抱歉,但如果你主张Common.getMD5HexDigest(文件)返回一个唯一的哈希我不信任你。 – jarnbjo 2012-02-20 17:19:38

+0

@jarnbjo我用方法代码更新了问题。 – Ben 2012-02-20 17:29:25

+0

所以你正在使用的散列不仅仅是非唯一的,而且也是不正确的。 – jarnbjo 2012-02-22 10:58:45

经过几个星期的MD5校验和问题(以验证文件内容是否随时间改变)后,我提出了一个不依赖于文件的MD5校验和的解决方案,但在客户端文件的last-update属性。

该解决方案去给大家,希望检查文件是否已随时间发生变化。然而,任何操作系统上的“更新”可被视为打开文件并将文件保存,使用或不使该文件的内容进行任何更改的行为。所以,这并不完美,但可以节省一些时间和带宽。

解决方案:

long lastModified = new DateTime(
    new Date(file.lastModified()), TimeZone.getDefault() 
).getValue(); 

if(lastModified > entry.getUpdated().getValue()) { 
    //update the file 
} 

哪里file是所需文件的File实例,entry是关联到本地文件DocumentListEntry

我猜想,你需要校验设置为文件的内容,在路径名不哈希的MD5哈希值。

为什么他们(谷歌)所关心的路径?这根本没有意义。如果我误解了你的代码,请原谅我,但我认为你错误地理解了文件校验和的概念。

无论如何,你需要做的是吃(摘要)的文件,而不是路径:

import java.security.*; 
    import java.util.*; 
    import java.math.*; 
    import java.io.*; 

    public class MD5 { 
     private MessageDigest mDigest; 
     private File   openFile; 
     private FileInputStream ofis; 
     private int    fSize; 
     private byte[]   fBytes; 

     public MD5(String filePath) { 
      try { mDigest = MessageDigest.getInstance("MD5"); } 
      catch (NoSuchAlgorithmException e) { System.exit(1); } 
      openFile = new File(filePath); 
     } 
     public String toString() { 
      try { 
       ofis = new FileInputStream(openFile); 
       fSize = ofis.available(); 
       fBytes = new byte[fSize]; 
       ofis.read(fBytes); 
      } catch (Throwable t) { 
       return "Can't read file or something"; 
      } 

      mDigest.update(fBytes); 
      return new BigInteger(1, mDigest.digest()).toString(16); 
     } 
     public static void main(String[] argv){ 
      MD5 md5 = new MD5("someFile.ext"); 
      System.out.println(md5); 
     } 
    } 

所以在上面的代码段错误是在这里:

messageDigest.update(String.valueOf(file.hashCode()).getBytes()); 

现在,我可以证明,我的课给文件这是最有可能你所需要的正确的md5sum。只要阅读方法的javadoc的,如果你不相信我: http://gdata-java-client.googlecode.com/svn/trunk/java/src/com/google/gdata/data/docs/DocumentListEntry.java 什么它说的是: *设置文档中计算的MD5校验。 ......一无所知路径的校验:)

这里:

$ echo "Two dogs are sleeping on my couch" > someFile.ext  
$ echo "Two dogs are sleeping on my couch" |md5sum 
1d81559b611e0079bf6c16a2c09bd994 - 
$ md5sum someFile.ext 
1d81559b611e0079bf6c16a2c09bd994 someFile.ext 
$ javac MD5.java && java MD5 
1d81559b611e0079bf6c16a2c09bd994 
+0

实际上,我现在看到您正在从Java的hashCode字符串中取得md5总和而不是路径。这是完全错误的。你需要md5-checksum-hash文件的肉体而不是一些随机的整数或任何File.hashCode()创建的。 – 2012-02-27 01:19:02

+0

已经这样做了,总是返回'null'。我猜目前不支持'setMD5Checksum'方法。 – Ben 2012-02-27 16:04:11