001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 package org.apache.hadoop.fs; 019 020 import java.io.DataInput; 021 import java.io.DataOutput; 022 import java.io.IOException; 023 024 import org.apache.hadoop.classification.InterfaceAudience; 025 import org.apache.hadoop.classification.InterfaceStability; 026 import org.apache.hadoop.fs.permission.FsPermission; 027 import org.apache.hadoop.io.Text; 028 import org.apache.hadoop.io.Writable; 029 030 /** Interface that represents the client side information for a file. 031 */ 032 @InterfaceAudience.Public 033 @InterfaceStability.Stable 034 public class FileStatus implements Writable, Comparable { 035 036 private Path path; 037 private long length; 038 private boolean isdir; 039 private short block_replication; 040 private long blocksize; 041 private long modification_time; 042 private long access_time; 043 private FsPermission permission; 044 private String owner; 045 private String group; 046 private Path symlink; 047 048 public FileStatus() { this(0, false, 0, 0, 0, 0, null, null, null, null); } 049 050 //We should deprecate this soon? 051 public FileStatus(long length, boolean isdir, int block_replication, 052 long blocksize, long modification_time, Path path) { 053 054 this(length, isdir, block_replication, blocksize, modification_time, 055 0, null, null, null, path); 056 } 057 058 /** 059 * Constructor for file systems on which symbolic links are not supported 060 */ 061 public FileStatus(long length, boolean isdir, 062 int block_replication, 063 long blocksize, long modification_time, long access_time, 064 FsPermission permission, String owner, String group, 065 Path path) { 066 this(length, isdir, block_replication, blocksize, modification_time, 067 access_time, permission, owner, group, null, path); 068 } 069 070 public FileStatus(long length, boolean isdir, 071 int block_replication, 072 long blocksize, long modification_time, long access_time, 073 FsPermission permission, String owner, String group, 074 Path symlink, 075 Path path) { 076 this.length = length; 077 this.isdir = isdir; 078 this.block_replication = (short)block_replication; 079 this.blocksize = blocksize; 080 this.modification_time = modification_time; 081 this.access_time = access_time; 082 this.permission = (permission == null) ? 083 FsPermission.getDefault() : permission; 084 this.owner = (owner == null) ? "" : owner; 085 this.group = (group == null) ? "" : group; 086 this.symlink = symlink; 087 this.path = path; 088 // The variables isdir and symlink indicate the type: 089 // 1. isdir implies directory, in which case symlink must be null. 090 // 2. !isdir implies a file or symlink, symlink != null implies a 091 // symlink, otherwise it's a file. 092 assert (isdir && symlink == null) || !isdir; 093 } 094 095 /** 096 * Get the length of this file, in bytes. 097 * @return the length of this file, in bytes. 098 */ 099 public long getLen() { 100 return length; 101 } 102 103 /** 104 * Is this a file? 105 * @return true if this is a file 106 */ 107 public boolean isFile() { 108 return !isdir && !isSymlink(); 109 } 110 111 /** 112 * Is this a directory? 113 * @return true if this is a directory 114 */ 115 public boolean isDirectory() { 116 return isdir; 117 } 118 119 /** 120 * Old interface, instead use the explicit {@link FileStatus#isFile()}, 121 * {@link FileStatus#isDirectory()}, and {@link FileStatus#isSymlink()} 122 * @return true if this is a directory. 123 * @deprecated Use {@link FileStatus#isFile()}, 124 * {@link FileStatus#isDirectory()}, and {@link FileStatus#isSymlink()} 125 * instead. 126 */ 127 @Deprecated 128 public boolean isDir() { 129 return isdir; 130 } 131 132 /** 133 * Is this a symbolic link? 134 * @return true if this is a symbolic link 135 */ 136 public boolean isSymlink() { 137 return symlink != null; 138 } 139 140 /** 141 * Get the block size of the file. 142 * @return the number of bytes 143 */ 144 public long getBlockSize() { 145 return blocksize; 146 } 147 148 /** 149 * Get the replication factor of a file. 150 * @return the replication factor of a file. 151 */ 152 public short getReplication() { 153 return block_replication; 154 } 155 156 /** 157 * Get the modification time of the file. 158 * @return the modification time of file in milliseconds since January 1, 1970 UTC. 159 */ 160 public long getModificationTime() { 161 return modification_time; 162 } 163 164 /** 165 * Get the access time of the file. 166 * @return the access time of file in milliseconds since January 1, 1970 UTC. 167 */ 168 public long getAccessTime() { 169 return access_time; 170 } 171 172 /** 173 * Get FsPermission associated with the file. 174 * @return permssion. If a filesystem does not have a notion of permissions 175 * or if permissions could not be determined, then default 176 * permissions equivalent of "rwxrwxrwx" is returned. 177 */ 178 public FsPermission getPermission() { 179 return permission; 180 } 181 182 /** 183 * Get the owner of the file. 184 * @return owner of the file. The string could be empty if there is no 185 * notion of owner of a file in a filesystem or if it could not 186 * be determined (rare). 187 */ 188 public String getOwner() { 189 return owner; 190 } 191 192 /** 193 * Get the group associated with the file. 194 * @return group for the file. The string could be empty if there is no 195 * notion of group of a file in a filesystem or if it could not 196 * be determined (rare). 197 */ 198 public String getGroup() { 199 return group; 200 } 201 202 public Path getPath() { 203 return path; 204 } 205 206 public void setPath(final Path p) { 207 path = p; 208 } 209 210 /* These are provided so that these values could be loaded lazily 211 * by a filesystem (e.g. local file system). 212 */ 213 214 /** 215 * Sets permission. 216 * @param permission if permission is null, default value is set 217 */ 218 protected void setPermission(FsPermission permission) { 219 this.permission = (permission == null) ? 220 FsPermission.getDefault() : permission; 221 } 222 223 /** 224 * Sets owner. 225 * @param owner if it is null, default value is set 226 */ 227 protected void setOwner(String owner) { 228 this.owner = (owner == null) ? "" : owner; 229 } 230 231 /** 232 * Sets group. 233 * @param group if it is null, default value is set 234 */ 235 protected void setGroup(String group) { 236 this.group = (group == null) ? "" : group; 237 } 238 239 /** 240 * @return The contents of the symbolic link. 241 */ 242 public Path getSymlink() throws IOException { 243 if (!isSymlink()) { 244 throw new IOException("Path " + path + " is not a symbolic link"); 245 } 246 return symlink; 247 } 248 249 public void setSymlink(final Path p) { 250 symlink = p; 251 } 252 253 ////////////////////////////////////////////////// 254 // Writable 255 ////////////////////////////////////////////////// 256 @Override 257 public void write(DataOutput out) throws IOException { 258 Text.writeString(out, getPath().toString(), Text.DEFAULT_MAX_LEN); 259 out.writeLong(getLen()); 260 out.writeBoolean(isDirectory()); 261 out.writeShort(getReplication()); 262 out.writeLong(getBlockSize()); 263 out.writeLong(getModificationTime()); 264 out.writeLong(getAccessTime()); 265 getPermission().write(out); 266 Text.writeString(out, getOwner(), Text.DEFAULT_MAX_LEN); 267 Text.writeString(out, getGroup(), Text.DEFAULT_MAX_LEN); 268 out.writeBoolean(isSymlink()); 269 if (isSymlink()) { 270 Text.writeString(out, getSymlink().toString(), Text.DEFAULT_MAX_LEN); 271 } 272 } 273 274 @Override 275 public void readFields(DataInput in) throws IOException { 276 String strPath = Text.readString(in, Text.DEFAULT_MAX_LEN); 277 this.path = new Path(strPath); 278 this.length = in.readLong(); 279 this.isdir = in.readBoolean(); 280 this.block_replication = in.readShort(); 281 blocksize = in.readLong(); 282 modification_time = in.readLong(); 283 access_time = in.readLong(); 284 permission.readFields(in); 285 owner = Text.readString(in, Text.DEFAULT_MAX_LEN); 286 group = Text.readString(in, Text.DEFAULT_MAX_LEN); 287 if (in.readBoolean()) { 288 this.symlink = new Path(Text.readString(in, Text.DEFAULT_MAX_LEN)); 289 } else { 290 this.symlink = null; 291 } 292 } 293 294 /** 295 * Compare this object to another object 296 * 297 * @param o the object to be compared. 298 * @return a negative integer, zero, or a positive integer as this object 299 * is less than, equal to, or greater than the specified object. 300 * 301 * @throws ClassCastException if the specified object's is not of 302 * type FileStatus 303 */ 304 @Override 305 public int compareTo(Object o) { 306 FileStatus other = (FileStatus)o; 307 return this.getPath().compareTo(other.getPath()); 308 } 309 310 /** Compare if this object is equal to another object 311 * @param o the object to be compared. 312 * @return true if two file status has the same path name; false if not. 313 */ 314 @Override 315 public boolean equals(Object o) { 316 if (o == null) { 317 return false; 318 } 319 if (this == o) { 320 return true; 321 } 322 if (!(o instanceof FileStatus)) { 323 return false; 324 } 325 FileStatus other = (FileStatus)o; 326 return this.getPath().equals(other.getPath()); 327 } 328 329 /** 330 * Returns a hash code value for the object, which is defined as 331 * the hash code of the path name. 332 * 333 * @return a hash code value for the path name. 334 */ 335 @Override 336 public int hashCode() { 337 return getPath().hashCode(); 338 } 339 }