View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.vfs2.provider.ftp;
18  
19  import java.io.DataInputStream;
20  import java.io.FilterInputStream;
21  import java.io.IOException;
22  
23  import org.apache.commons.io.IOUtils;
24  import org.apache.commons.vfs2.FileSystemException;
25  import org.apache.commons.vfs2.provider.AbstractRandomAccessStreamContent;
26  import org.apache.commons.vfs2.util.RandomAccessMode;
27  
28  /**
29   * Implements FTP stream-based random access.
30   */
31  final class FtpRandomAccessContent extends AbstractRandomAccessStreamContent {
32  
33      protected long filePointer;
34  
35      private final FtpFileObject fileObject;
36      private DataInputStream dis;
37      private FtpFileObject.FtpInputStream mis;
38  
39      FtpRandomAccessContent(final FtpFileObject fileObject, final RandomAccessMode mode) {
40          super(mode);
41  
42          this.fileObject = fileObject;
43          // fileSystem = (FtpFileSystem) this.fileObject.getFileSystem();
44      }
45  
46      @Override
47      public void close() throws IOException {
48          if (dis != null) {
49              mis.abort();
50  
51              // this is to avoid recursive close
52              final DataInputStream oldDis = dis;
53              dis = null;
54              oldDis.close();
55              mis = null;
56          }
57      }
58  
59      @Override
60      protected DataInputStream getDataInputStream() throws IOException {
61          if (dis != null) {
62              return dis;
63          }
64  
65          // FtpClient client = fileSystem.getClient();
66          mis = fileObject.getInputStream(filePointer);
67          dis = new DataInputStream(new FilterInputStream(mis) {
68              @Override
69              public void close() throws IOException {
70                  FtpRandomAccessContent.this.close();
71              }
72  
73              @Override
74              public int read() throws IOException {
75                  final int ret = super.read();
76                  if (ret > -1) {
77                      filePointer++;
78                  }
79                  return ret;
80              }
81  
82              @Override
83              public int read(final byte[] b) throws IOException {
84                  final int ret = super.read(b);
85                  if (ret > -1) {
86                      filePointer += ret;
87                  }
88                  return ret;
89              }
90  
91              @Override
92              public int read(final byte[] b, final int off, final int len) throws IOException {
93                  final int ret = super.read(b, off, len);
94                  if (ret > -1) {
95                      filePointer += ret;
96                  }
97                  return ret;
98              }
99          });
100 
101         return dis;
102     }
103 
104     @Override
105     public long getFilePointer() throws IOException {
106         return filePointer;
107     }
108 
109     @Override
110     public long length() throws IOException {
111         return fileObject.getContent().getSize();
112     }
113 
114     @Override
115     public void seek(final long pos) throws IOException {
116         if (pos == filePointer) {
117             // no change
118             return;
119         }
120         if (pos < 0) {
121             throw new FileSystemException("vfs.provider/random-access-invalid-position.error", Long.valueOf(pos));
122         }
123         IOUtils.close(dis);
124         filePointer = pos;
125     }
126 }