【问题标题】:How do I retrieve the modified date for the file?如何检索文件的修改日期?
【发布时间】:2013-06-27 14:29:46
【问题描述】:

在我的程序中,我试图获取我的文件夹中某些项目的最后修改日期,但我无法访问该信息。

根据box API的文档和java库的javadoc,BoxTypedObject的以下任何方法都应该返回我想要的信息:

  • getModifiedAt() 应以 ISO 8601 格式返回 String 日期。
  • getModifiedDate() 应该为日期返回一个 Date 对象。
  • getValue("modified_at") 还应该返回一个 ISO 8601 格式的 String 作为日期。
  • getExtraData("modified_at") 也是一种可能的方式,虽然我不太确定。

但是,这些方法都不适合我;他们都只是返回null

我用来检索日期的(大大简化的)代码如下,上面的方法之一代替了注释块:

private static void printAll(BoxFolder boxFolder){
    for(BoxTypedObject file : boxFolder.getItemCollection().getEntries())
        System.out.printf("[\"%1$s\" %2$s]%n",
                file.getValue("name"), file./*[???]*/);
}

其他字段都返回正确的值,只有当我尝试获取日期时它才会失败。

如何检索BoxTypedObjects 的修改日期?

编辑:我想出了一种方法来获得它,但它有点慢。

client.getFilesManager().getFile(file.getId(), null).getModifiedAt()

检索日期。不过,如果有更好的方法,我仍然很感兴趣。


其他信息(可能与问题相关,也可能不相关):

盒子客户端的认证由以下类处理:

import java.awt.Desktop;
import java.io.*;
import java.net.*;
import com.box.boxjavalibv2.BoxClient;
import com.box.boxjavalibv2.dao.BoxOAuthToken;
import com.box.boxjavalibv2.exceptions.*;
import com.box.boxjavalibv2.requests.requestobjects.BoxOAuthRequestObject;
import com.box.restclientv2.exceptions.BoxRestException;

/**
 * This class handles the storage and use of authentication keys, to
 * simplify the process of obtaining n authenticated client.  This class
 * will store refresh keys in a file, so that it can authenticate a client
 * without needing for user intervention.
 * <p>
 * Copyright 2013 Mallick Mechanical, Inc.
 * 
 * @author Anson Mansfield
 */
public class Authenticator {

    /**
     * Constructs an {@code Authenticator} for use obtaining
     * authenticated {@Code BoxClient}s
     * 
     * @param key The OAuth client id and application key.
     * @param secret The OAuth client secret.
     * @param authFile The file to be used for storing authentications
     * for later use.
     */
    public Authenticator(String key, String secret, File authFile){
        this.key = key;
        this.secret = secret;
        this.authFile = authFile;
    }

    /**
     * Constructs a new {@Code BoxClient} object, authenticates it,
     * and returns it.
     */
    public BoxClient getAuthenticatedClient(){
        BoxClient client = new BoxClient(key,secret);
        client.authenticate(getToken(client));
        return client;
    }
    public final String host = "http://localhost";
    public final int port = 4000;
    public final String key, secret;
    public final File authFile;
    public final String url = "https://www.box.com/api/oauth2/authorize?response_type=code&client_id=";

    /**
     * Obtains a token that can be used to authenticate the box client,
     * and stores its refresh value in a file, so it can be used later.
     * @param client The client to obtain a token for.
     * @return A token that can be used to authenticate the client, or
     * {@code null} if one could not be obtained.
     */
    private BoxOAuthToken getToken(BoxClient client){
        BoxOAuthToken token = null;
        try{
            if((token = getOldToken(client)) != null) return token;
            if((token = getNewToken(client)) != null) return token;
            return token;
        }finally{
            writeNewToken(token);
        }
    }

    /**
     * Attempts to write a token's refresh token to a file.
     * @param token The token whose refresh value is to be written.
     */
    private void writeNewToken(BoxOAuthToken token) {
        if(token != null)
            try(BufferedWriter out = new BufferedWriter(new FileWriter(authFile))){
                out.write(token.getRefreshToken());
            }catch(IOException ex){
                System.out.println("couldn't update new token");
            }
    }

    /**
     * Reads the last session's refresh token from a file and attempts
     * to get a new authentication token with it.
     * @param client The client for which the authentication token is for.
     * @return The token obtained from the refresh, or {@code null} if one
     * could not be obtained.
     */
    private BoxOAuthToken getOldToken(BoxClient client) {
        System.out.println("attempting to use old token");
        BoxOAuthToken token = null;
        try(BufferedReader in = new BufferedReader(new FileReader(authFile))){
            token = client.getOAuthManager().refreshOAuth(
                    BoxOAuthRequestObject.refreshOAuthRequestObject(
                            in.readLine(), key, secret
                            ));
            System.out.println("refreshed old token");
        }catch(IOException ex){
            System.out.println("couldn't read old token");
        } catch(BoxRestException | BoxServerException | AuthFatalFailureException ex){
            System.out.println("couldn't refresh old token");
        }
        return token;
    }

    /**
     * Connects to the OAuth server and gets a new authentication token.
     * @param client The client to get a token for.
     * @return The new token obtained from the server, or {@code null} if one could not be obtained.
     */
    private BoxOAuthToken getNewToken(BoxClient client) {
        System.out.println("attempting to get new token");
        BoxOAuthToken token = null;
        try {
            Desktop.getDesktop().browse(java.net.URI.create(url + key));
            token = client.getOAuthManager().createOAuth(
                    BoxOAuthRequestObject.createOAuthRequestObject(getCode(), key, secret, host + port)
                    );
        } catch (BoxRestException | BoxServerException |  AuthFatalFailureException | IOException ex) {
            ex.printStackTrace();
            return null;
        }
        return token;
    }

    /**
     * This listens on the configured port for the code included in the callback.
     * It also deploys a script on the receiving socket to close the browser tab navigating to it.
     * @return The authentication code to generate a token with.
     */
    private String getCode(){
        try (ServerSocket serverSocket = new ServerSocket(port);
                Socket socket = serverSocket.accept();
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter out = new PrintWriter(socket.getOutputStream());){
            out.println("<script type=\"text/javascript\">");
            out.println(    "window.open('', '_self', '');");
            out.println(    "window.close();");
            out.println("</script>"); //Close the tab
            while (true){
                String code = "";
                code = in.readLine ();
                System.out.println(code);
                String match = "code";
                int loc = code.indexOf(match);
                if( loc >0 ) {
                    int httpstr = code.indexOf("HTTP")-1;
                    code = code.substring(code.indexOf(match), httpstr);
                    String parts[] = code.split("=");
                    code=parts[1];
                    return code;
                } else {
                    // It doesn't have a code
                }
            }
        } catch (IOException | NullPointerException e) {
            return "";
        }
    }
}

将获得修改字段的实际类(但尚未完成):

import java.io.File;
import java.util.Scanner;
import com.box.boxjavalibv2.BoxClient;
import com.box.boxjavalibv2.dao.BoxFolder;
import com.box.boxjavalibv2.dao.BoxTypedObject;

/**
 * Copyright 2013 Mallick Mechanical, Inc.
 * 
 * @author Anson Mansfield
 */
public class BoxStuff {
    static BoxClient client;
    public void main(String ... args) throws Exception {
        client = new Authenticator(args[0], args[1], new File(args[2]))
        .getAuthenticatedClient();
        userSelectFolder("Select the project folder");
    }
    private static BoxFolder userSelectFolder(String prompt) throws Exception{
        Scanner kbd;
        if(System.console()!=null)
            kbd = new Scanner(System.console().reader());
        else
            kbd = new Scanner(System.in);

        String line = "";

        System.out.println();
        System.out.println(prompt);
        System.out.println("(leave prompt blank to select folder)");
        BoxFolder current = client.getFoldersManager().getFolder("0", null);
        printAll(current);
        System.out.print("select>");
        while(!(line = kbd.nextLine()).isEmpty()){
            BoxFolder next = select(current, Integer.parseInt(line));
            if(next != null) current = next;
            printAll(current);
            System.out.print("select>");
        }
        return current;
    }
    private static void printAll(BoxFolder boxFolder){
        int idx=0;
        System.out.println("  0:[parent folder]");
        for(BoxTypedObject file : boxFolder
                .getItemCollection()
                .getEntries()){
            if(file.getType().equals("folder")){
                System.out.printf("%1$3d:[%2$-32s %3$-6s %4$-9s]%n",
                        ++idx, format((String) file.getValue("name"),30), file.getType(), file.getId());
            } else {
                System.out.printf("    [%1$-32s %2$-6s %3$-9s Edit:%4$s]%n",
                        format((String) file.getValue("name"),32), file.getType(), file.getId(), file.getExtraData("modified_at"));
            }
        }
    }
    private static String format(CharSequence source, int length){
        StringBuilder b = new StringBuilder(length);

        b.append('"');

        if(source.length() > 30)
            b.append(source.subSequence(0, 29)).append('~');
        else
            b.append(String.format("%1$-30s",source));
        b.append('"');
        return b.toString();
    }
    private static BoxFolder select(BoxFolder boxFolder, int i) throws Exception{
        int idx=0;
        for(BoxTypedObject file : boxFolder.getItemCollection().getEntries()){
            if(file.getType().equals("folder") && ++idx == i){
                return client.getFoldersManager().getFolder(file.getId(), null);
            }
        }

        if(idx==0){
            if(boxFolder.getParent() == null)
                return client.getFoldersManager().getFolder("0", null);
            else
                return client.getFoldersManager().getFolder(boxFolder.getParent().getId(), null);
        }else{
            System.out.println("Selection is out of range!");
            return boxFolder;
        }
    }
}

如果其他人想使用这些类做某事,请问我。应该没问题(他们是机械承包商,不是软件公司),我只需要和老板说清楚(这个代码仍然属于公司)。

【问题讨论】:

    标签: java box-api last-modified


    【解决方案1】:

    这实际上有点棘手。默认情况下获取文件夹项目的 api 调用仅返回具有一些默认字段的子项目,它们不包括诸如 modified_at 之类的字段。但是,如果您提供额外的字段参数,您应该能够获得它们。

    以下是使用 getFolderItems 方法时可以执行的操作(这也在 github 的自述文件中): BoxFolderRequestObject requestObj = BoxFolderRequestObject.getFolderItemsRequestObject(30, 20) .addField(BoxFolder.FIELD_NAME) .addField(BoxFolder.FIELD_MODIFIED_AT); BoxCollection collection = boxClient.getFoldersManager().getFolderItems(folderId, requestObj);

    这里还有一个棘手的问题,在您提供这些字段后,结果子项将仅包含提供的字段(加上一些基本字段),因此请确保添加所有您想要的字段。

    【讨论】:

    【解决方案2】:

    这是我想出的一种方法(确实有效):

    client.getFilesManager().getFile(file.getId(), null).getModifiedAt()
    

    但是,这有点慢,所以如果其他人知道更快的解决方案,我将不胜感激。

    【讨论】:

      猜你喜欢
      • 2012-11-09
      • 1970-01-01
      • 1970-01-01
      • 2015-01-16
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多