1 // 2 // ======================================================================== 3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 4 // ------------------------------------------------------------------------ 5 // All rights reserved. This program and the accompanying materials 6 // are made available under the terms of the Eclipse Public License v1.0 7 // and Apache License v2.0 which accompanies this distribution. 8 // 9 // The Eclipse Public License is available at 10 // http://www.eclipse.org/legal/epl-v10.html 11 // 12 // The Apache License v2.0 is available at 13 // http://www.opensource.org/licenses/apache2.0.php 14 // 15 // You may elect to redistribute this code under either of these licenses. 16 // ======================================================================== 17 // 18 19 package org.eclipse.jetty.io.nio; 20 21 import java.io.File; 22 import java.io.FileNotFoundException; 23 import java.io.IOException; 24 import java.io.RandomAccessFile; 25 import java.nio.channels.FileChannel; 26 import java.nio.channels.WritableByteChannel; 27 28 import org.eclipse.jetty.io.AbstractBuffer; 29 import org.eclipse.jetty.io.Buffer; 30 31 public class RandomAccessFileBuffer extends AbstractBuffer implements Buffer 32 { 33 final RandomAccessFile _file; 34 final FileChannel _channel; 35 final int _capacity; 36 37 public RandomAccessFileBuffer(File file) 38 throws FileNotFoundException 39 { 40 super(READWRITE,true); 41 assert file.length()<=Integer.MAX_VALUE; 42 _file = new RandomAccessFile(file,"rw"); 43 _channel=_file.getChannel(); 44 _capacity=Integer.MAX_VALUE; 45 setGetIndex(0); 46 setPutIndex((int)file.length()); 47 } 48 49 public RandomAccessFileBuffer(File file,int capacity) 50 throws FileNotFoundException 51 { 52 super(READWRITE,true); 53 assert capacity>=file.length(); 54 assert file.length()<=Integer.MAX_VALUE; 55 _capacity=capacity; 56 _file = new RandomAccessFile(file,"rw"); 57 _channel=_file.getChannel(); 58 setGetIndex(0); 59 setPutIndex((int)file.length()); 60 } 61 62 public RandomAccessFileBuffer(File file,int capacity,int access) 63 throws FileNotFoundException 64 { 65 super(access,true); 66 assert capacity>=file.length(); 67 assert file.length()<=Integer.MAX_VALUE; 68 _capacity=capacity; 69 _file = new RandomAccessFile(file,access==READWRITE?"rw":"r"); 70 _channel=_file.getChannel(); 71 setGetIndex(0); 72 setPutIndex((int)file.length()); 73 } 74 75 public byte[] array() 76 { 77 return null; 78 } 79 80 public int capacity() 81 { 82 return _capacity; 83 } 84 85 @Override 86 public void clear() 87 { 88 try 89 { 90 synchronized (_file) 91 { 92 super.clear(); 93 _file.setLength(0); 94 } 95 } 96 catch(Exception e) 97 { 98 throw new RuntimeException(e); 99 } 100 } 101 102 103 @Override 104 public byte peek() 105 { 106 synchronized (_file) 107 { 108 try 109 { 110 if (_get!=_file.getFilePointer()) 111 _file.seek(_get); 112 return _file.readByte(); 113 } 114 catch(Exception e) 115 { 116 throw new RuntimeException(e); 117 } 118 } 119 } 120 121 public byte peek(int index) 122 { 123 synchronized (_file) 124 { 125 try 126 { 127 _file.seek(index); 128 return _file.readByte(); 129 } 130 catch(Exception e) 131 { 132 throw new RuntimeException(e); 133 } 134 } 135 } 136 137 public int peek(int index, byte[] b, int offset, int length) 138 { 139 synchronized (_file) 140 { 141 try 142 { 143 _file.seek(index); 144 return _file.read(b,offset,length); 145 } 146 catch(Exception e) 147 { 148 throw new RuntimeException(e); 149 } 150 } 151 } 152 153 public void poke(int index, byte b) 154 { 155 synchronized (_file) 156 { 157 try 158 { 159 _file.seek(index); 160 _file.writeByte(b); 161 } 162 catch(Exception e) 163 { 164 throw new RuntimeException(e); 165 } 166 } 167 } 168 169 @Override 170 public int poke(int index, byte[] b, int offset, int length) 171 { 172 synchronized (_file) 173 { 174 try 175 { 176 _file.seek(index); 177 _file.write(b,offset,length); 178 return length; 179 } 180 catch(Exception e) 181 { 182 throw new RuntimeException(e); 183 } 184 } 185 } 186 187 public int writeTo(WritableByteChannel channel,int index, int length) 188 throws IOException 189 { 190 synchronized (_file) 191 { 192 return (int)_channel.transferTo(index,length,channel); 193 } 194 } 195 196 } 197