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 public void write(DataOutput out) throws IOException {
257 Text.writeString(out, getPath().toString());
258 out.writeLong(getLen());
259 out.writeBoolean(isDirectory());
260 out.writeShort(getReplication());
261 out.writeLong(getBlockSize());
262 out.writeLong(getModificationTime());
263 out.writeLong(getAccessTime());
264 getPermission().write(out);
265 Text.writeString(out, getOwner());
266 Text.writeString(out, getGroup());
267 out.writeBoolean(isSymlink());
268 if (isSymlink()) {
269 Text.writeString(out, getSymlink().toString());
270 }
271 }
272
273 public void readFields(DataInput in) throws IOException {
274 String strPath = Text.readString(in);
275 this.path = new Path(strPath);
276 this.length = in.readLong();
277 this.isdir = in.readBoolean();
278 this.block_replication = in.readShort();
279 blocksize = in.readLong();
280 modification_time = in.readLong();
281 access_time = in.readLong();
282 permission.readFields(in);
283 owner = Text.readString(in);
284 group = Text.readString(in);
285 if (in.readBoolean()) {
286 this.symlink = new Path(Text.readString(in));
287 } else {
288 this.symlink = null;
289 }
290 }
291
292 /**
293 * Compare this object to another object
294 *
295 * @param o the object to be compared.
296 * @return a negative integer, zero, or a positive integer as this object
297 * is less than, equal to, or greater than the specified object.
298 *
299 * @throws ClassCastException if the specified object's is not of
300 * type FileStatus
301 */
302 public int compareTo(Object o) {
303 FileStatus other = (FileStatus)o;
304 return this.getPath().compareTo(other.getPath());
305 }
306
307 /** Compare if this object is equal to another object
308 * @param o the object to be compared.
309 * @return true if two file status has the same path name; false if not.
310 */
311 public boolean equals(Object o) {
312 if (o == null) {
313 return false;
314 }
315 if (this == o) {
316 return true;
317 }
318 if (!(o instanceof FileStatus)) {
319 return false;
320 }
321 FileStatus other = (FileStatus)o;
322 return this.getPath().equals(other.getPath());
323 }
324
325 /**
326 * Returns a hash code value for the object, which is defined as
327 * the hash code of the path name.
328 *
329 * @return a hash code value for the path name.
330 */
331 public int hashCode() {
332 return getPath().hashCode();
333 }
334 }