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