【问题标题】:Google Docs API "setMd5Checksum" not workingGoogle Docs API“setMd5C​​hecksum”不起作用
【发布时间】:2012-02-20 17:09:17
【问题描述】:

最近我在Java 中实现了一个使用Google Docs API v3.0 的应用程序。新条目是这样创建的:

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 或服务器生成的字符串)。

【问题讨论】:

  • 抱歉,如果你声称 Common.getMD5HexDigest(file) 返回一个唯一的哈希值,我不相信你。
  • @jarnbjo 我已经用方法代码更新了问题。
  • 因此,您使用的哈希不仅不唯一,而且也不正确。
  • @jarnbjo 它是唯一的,因为它是文件路径哈希的 MD5 哈希(对于任何给定 PC 中的 Windows 文件系统中的每个文件都是唯一的)。为什么它不正确?我看到 32 字节的十六进制数据。
  • 挑剔,输入可能是唯一的,但输出可能不是。

标签: java md5 google-docs-api


【解决方案1】:

我猜您需要将校验和设置为文件 contents 的 md5 哈希,而不是 path-name 的哈希>。

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

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

   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);
       }  
   } 

所以上面的sn-p中的错误在这里:

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

现在,我可以证明我的班级给出了 file 的正确 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

【讨论】:

  • 实际上,我现在看到您正在从 Java 的 hashCode-string 而不是路径中进行 md5 总和。这是完全错误的。您需要 md5-checksum-hash 文件的内容,而不是一些随机整数或 File.hashCode() 创建的任何内容。
  • 已经这样做了,总是返回null。我猜目前不支持setMD5Checksum 方法。
【解决方案2】:

在与 MD5 校验和问题(以验证文件的内容是否随时间变化)苦苦挣扎了几周之后,我想出了一个不依赖于文件的 MD5 校验和而是依赖于客户端的解决方案@ 987654321@文件的属性。

此解决方案适用于所有想要检查文件是否随时间变化的人。但是,任何操作系统上的“更新”都可以被视为打开文件并保存文件的行为,无论是否对文件内容进行任何更改。因此,它并不完美,但确实节省了一些时间和带宽。

解决方案:

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

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

其中file 是所需文件的File 实例,entry 是与本地文件关联的DocumentListEntry

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多