Java tutorial
/** * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ package com.buaa.cfs.nfs3; import com.buaa.cfs.common.oncrpc.XDR; import org.apache.commons.io.Charsets; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.nio.ByteBuffer; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; /** * This is a file handle use by the NFS clients. Server returns this handle to the client, which is used by the client * on subsequent operations to reference the file. */ public class FileHandle { private static final Log LOG = LogFactory.getLog(FileHandle.class); private static final String HEXES = "0123456789abcdef"; private static final int HANDLE_LEN = 32; private byte[] handle; // Opaque handle private long fileId = -1; public FileHandle() { handle = null; } /** * Handle is a 32 bytes number. For HDFS, the last 8 bytes is fileId. */ public FileHandle(long v) { fileId = v; handle = new byte[HANDLE_LEN]; handle[0] = (byte) (v >>> 56); handle[1] = (byte) (v >>> 48); handle[2] = (byte) (v >>> 40); handle[3] = (byte) (v >>> 32); handle[4] = (byte) (v >>> 24); handle[5] = (byte) (v >>> 16); handle[6] = (byte) (v >>> 8); handle[7] = (byte) (v >>> 0); for (int i = 8; i < HANDLE_LEN; i++) { handle[i] = (byte) 0; } } public FileHandle(String s) { MessageDigest digest; try { digest = MessageDigest.getInstance("MD5"); handle = new byte[HANDLE_LEN]; } catch (NoSuchAlgorithmException e) { LOG.warn("MD5 MessageDigest unavailable."); handle = null; return; } byte[] in = s.getBytes(Charsets.UTF_8); digest.update(in); byte[] digestbytes = digest.digest(); for (int i = 0; i < 16; i++) { handle[i] = (byte) 0; } for (int i = 16; i < 32; i++) { handle[i] = digestbytes[i - 16]; } } public boolean serialize(XDR out) { out.writeInt(handle.length); out.writeFixedOpaque(handle); return true; } private long bytesToLong(byte[] data) { ByteBuffer buffer = ByteBuffer.allocate(8); for (int i = 0; i < 8; i++) { buffer.put(data[i]); } buffer.flip();// need flip return buffer.getLong(); } public boolean deserialize(XDR xdr) { if (!XDR.verifyLength(xdr, 32)) { return false; } int size = xdr.readInt(); handle = xdr.readFixedOpaque(size); fileId = bytesToLong(handle); return true; } private static String hex(byte b) { StringBuilder strBuilder = new StringBuilder(); strBuilder.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F))); return strBuilder.toString(); } public long getFileId() { return fileId; } public byte[] getContent() { return handle.clone(); } @Override public String toString() { StringBuilder s = new StringBuilder(); for (int i = 0; i < handle.length; i++) { s.append(hex(handle[i])); } return s.toString(); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof FileHandle)) { return false; } FileHandle h = (FileHandle) o; return Arrays.equals(handle, h.handle); } @Override public int hashCode() { return Arrays.hashCode(handle); } }