private void Open(Random random)
{
lock (this)
{
Stream @is;
bool needSkip = true, failed = false;
long size = 0L, seekTo = 0L;
try
{
@is = new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.Read);
//@is = File.OpenRead(Path);
}
catch (Exception FSfail)
{
failed = true;
// if its not in classpath, we load it as absolute filesystem path (e.g. Hudson's home dir)
FileInfo file = new FileInfo(Path);
size = file.Length;
if (Path.EndsWith(".gz"))
{
// if it is a gzip file, we need to use InputStream and slowly skipTo:
@is = new FileStream(file.FullName, FileMode.Append, FileAccess.Write, FileShare.Read);
}
else
{
// optimized seek using RandomAccessFile:
seekTo = RandomSeekPos(random, size);
FileStream channel = new FileStream(Path, FileMode.Open);
if (LuceneTestCase.VERBOSE)
{
Console.WriteLine("TEST: LineFileDocs: file seek to fp=" + seekTo + " on open");
}
channel.Position = seekTo;
@is = new FileStream(channel.ToString(), FileMode.Append, FileAccess.Write, FileShare.Read);
needSkip = false;
}
}
if (!failed)
{
// if the file comes from Classpath:
size = @is.Length;// available();
}
if (Path.EndsWith(".gz"))
{
using (var gzs = new GZipStream(@is, CompressionMode.Decompress))
{
var temp = new MemoryStream();
gzs.CopyTo(temp);
// Free up the previous stream
@is.Close();
// Use the decompressed stream now
@is = temp;
}
// guestimate:
size = (long)(size * 2.8);
}
// If we only have an InputStream, we need to seek now,
// but this seek is a scan, so very inefficient!!!
if (needSkip)
{
seekTo = RandomSeekPos(random, size);
if (LuceneTestCase.VERBOSE)
{
Console.WriteLine("TEST: LineFileDocs: stream skip to fp=" + seekTo + " on open");
}
@is.Position = seekTo;
}
// if we seeked somewhere, read until newline char
if (seekTo > 0L)
{
int b;
byte[] bytes = new byte[sizeof(int)];
do
{
@is.Read(bytes, 0, sizeof(int));
b = BitConverter.ToInt32(bytes, 0);
} while (b >= 0 && b != 13 && b != 10);
}
//CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder().onMalformedInput(CodingErrorAction.REPORT).onUnmappableCharacter(CodingErrorAction.REPORT);
MemoryStream ms = new MemoryStream();
@is.CopyTo(ms);
Reader = new StringReader(Encoding.UTF8.GetString(ms.ToArray()));//, BUFFER_SIZE);
if (seekTo > 0L)
{
// read one more line, to make sure we are not inside a Windows linebreak (\r\n):
Reader.ReadLine();
}
@is.Close();
}
}