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.vfs2.FileSystemException;
24  import org.apache.commons.vfs2.provider.AbstractRandomAccessStreamContent;
25  import org.apache.commons.vfs2.util.RandomAccessMode;
26  
27  /**
28   * Implements FTP stream-based random access.
29   */
30  class FtpRandomAccessContent extends AbstractRandomAccessStreamContent {
31  
32      protected long filePointer;
33  
34      private final FtpFileObject fileObject;
35      private DataInputStream dis;
36      private FtpFileObject.FtpInputStream mis;
37  
38      FtpRandomAccessContent(final FtpFileObject fileObject, final RandomAccessMode mode) {
39          super(mode);
40  
41          this.fileObject = fileObject;
42          // fileSystem = (FtpFileSystem) this.fileObject.getFileSystem();
43      }
44  
45      @Override
46      public long getFilePointer() throws IOException {
47          return filePointer;
48      }
49  
50      @Override
51      public void seek(final long pos) throws IOException {
52          if (pos == filePointer) {
53              // no change
54              return;
55          }
56  
57          if (pos < 0) {
58              throw new FileSystemException("vfs.provider/random-access-invalid-position.error", Long.valueOf(pos));
59          }
60          if (dis != null) {
61              close();
62          }
63  
64          filePointer = pos;
65      }
66  
67      @Override
68      protected DataInputStream getDataInputStream() throws IOException {
69          if (dis != null) {
70              return dis;
71          }
72  
73          // FtpClient client = fileSystem.getClient();
74          mis = fileObject.getInputStream(filePointer);
75          dis = new DataInputStream(new FilterInputStream(mis) {
76              @Override
77              public int read() throws IOException {
78                  final int ret = super.read();
79                  if (ret > -1) {
80                      filePointer++;
81                  }
82                  return ret;
83              }
84  
85              @Override
86              public int read(final byte[] b) throws IOException {
87                  final int ret = super.read(b);
88                  if (ret > -1) {
89                      filePointer += ret;
90                  }
91                  return ret;
92              }
93  
94              @Override
95              public int read(final byte[] b, final int off, final int len) throws IOException {
96                  final int ret = super.read(b, off, len);
97                  if (ret > -1) {
98                      filePointer += ret;
99                  }
100                 return ret;
101             }
102 
103             @Override
104             public void close() throws IOException {
105                 FtpRandomAccessContent.this.close();
106             }
107         });
108 
109         return dis;
110     }
111 
112     @Override
113     public void close() throws IOException {
114         if (dis != null) {
115             mis.abort();
116 
117             // this is to avoid recursive close
118             final DataInputStream oldDis = dis;
119             dis = null;
120             oldDis.close();
121             mis = null;
122         }
123     }
124 
125     @Override
126     public long length() throws IOException {
127         return fileObject.getContent().getSize();
128     }
129 }