Skip to content

Commit aad28d7

Browse files
author
rstam
committed
Fixed CSHARP-484. Fixed some issues with GridFS with files larger than 2GB.
1 parent 81a4762 commit aad28d7

File tree

2 files changed

+19
-19
lines changed

2 files changed

+19
-19
lines changed

Driver/GridFS/MongoGridFS.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ public void Download(Stream stream, MongoGridFSFileInfo fileInfo)
267267
using (var md5Algorithm = _settings.VerifyMD5 ? MD5.Create() : null)
268268
{
269269
var numberOfChunks = (fileInfo.Length + fileInfo.ChunkSize - 1) / fileInfo.ChunkSize;
270-
for (int n = 0; n < numberOfChunks; n++)
270+
for (var n = 0L; n < numberOfChunks; n++)
271271
{
272272
var query = Query.And(Query.EQ("files_id", fileInfo.Id), Query.EQ("n", n));
273273
var chunk = _chunks.FindOne(query);
@@ -785,11 +785,11 @@ public MongoGridFSFileInfo Upload(
785785
var chunkSize = createOptions.ChunkSize == 0 ? _settings.ChunkSize : createOptions.ChunkSize;
786786
var buffer = new byte[chunkSize];
787787

788-
var length = 0;
788+
var length = 0L;
789789
string md5Client = null;
790790
using (var md5Algorithm = _settings.VerifyMD5 ? MD5.Create() : null)
791791
{
792-
for (int n = 0; true; n++)
792+
for (var n = 0L; true; n++)
793793
{
794794
// might have to call Stream.Read several times to get a whole chunk
795795
var bytesNeeded = chunkSize;
@@ -821,7 +821,7 @@ public MongoGridFSFileInfo Upload(
821821
{
822822
{ "_id", BsonObjectId.GenerateNewId() },
823823
{ "files_id", files_id },
824-
{ "n", n },
824+
{ "n", (n < int.MaxValue) ? (BsonValue)BsonInt32.Create((int)n) : BsonInt64.Create(n) },
825825
{ "data", new BsonBinaryData(data) }
826826
};
827827
_chunks.Insert(chunk, _settings.SafeMode);

Driver/GridFS/MongoGridFSStream.cs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class MongoGridFSStream : Stream
4040
private long _length;
4141
private long _position;
4242
private byte[] _chunk;
43-
private int _chunkIndex = -1; // -1 means no chunk is loaded
43+
private long _chunkIndex = -1; // -1 means no chunk is loaded
4444
private BsonValue _chunkId;
4545
private bool _chunkIsDirty;
4646
private bool _fileIsDirty;
@@ -248,7 +248,7 @@ public override int Read(byte[] buffer, int offset, int count)
248248
if (_disposed) { throw new ObjectDisposedException("MongoGridFSStream"); }
249249
var available = _length - _position;
250250
if (count > available) { count = (int)available; }
251-
var chunkIndex = (int)(_position / _fileInfo.ChunkSize);
251+
var chunkIndex = _position / _fileInfo.ChunkSize;
252252
var chunkOffset = (int)(_position % _fileInfo.ChunkSize);
253253
var bytesRead = 0;
254254
while (count > 0)
@@ -276,7 +276,7 @@ public override int ReadByte()
276276
if (_disposed) { throw new ObjectDisposedException("MongoGridFSStream"); }
277277
if (_position < _length)
278278
{
279-
var chunkIndex = (int)(_position / _fileInfo.ChunkSize);
279+
var chunkIndex = _position / _fileInfo.ChunkSize;
280280
var chunkOffset = (int)(_position % _fileInfo.ChunkSize);
281281
if (_chunkIndex != chunkIndex) { LoadChunk(chunkIndex); }
282282
var b = _chunk[chunkOffset];
@@ -328,7 +328,7 @@ public override void SetLength(long value)
328328
}
329329
_fileIsDirty = true;
330330

331-
var lastChunkIndex = (int)((_length + _fileInfo.ChunkSize - 1) / _fileInfo.ChunkSize) - 1;
331+
var lastChunkIndex = ((_length + _fileInfo.ChunkSize - 1) / _fileInfo.ChunkSize) - 1;
332332
if (_chunkIndex == lastChunkIndex)
333333
{
334334
// if the current chunk is the new last chunk mark it dirty (its size has changed)
@@ -352,7 +352,7 @@ public override void SetLength(long value)
352352
public override void Write(byte[] buffer, int offset, int count)
353353
{
354354
if (_disposed) { throw new ObjectDisposedException("MongoGridFSStream"); }
355-
var chunkIndex = (int)(_position / _fileInfo.ChunkSize);
355+
var chunkIndex = _position / _fileInfo.ChunkSize;
356356
var chunkOffset = (int)(_position % _fileInfo.ChunkSize);
357357
while (count > 0)
358358
{
@@ -398,7 +398,7 @@ public override void Write(byte[] buffer, int offset, int count)
398398
public override void WriteByte(byte value)
399399
{
400400
if (_disposed) { throw new ObjectDisposedException("MongoGridFSStream"); }
401-
var chunkIndex = (int)(_position / _fileInfo.ChunkSize);
401+
var chunkIndex = _position / _fileInfo.ChunkSize;
402402
var chunkOffset = (int)(_position % _fileInfo.ChunkSize);
403403
if (_chunkIndex != chunkIndex)
404404
{
@@ -448,12 +448,12 @@ private void AddMissingChunks()
448448
{
449449
var query = Query.EQ("files_id", _fileInfo.Id);
450450
var fields = Fields.Include("n");
451-
var chunkCount = (int)((_length + _fileInfo.ChunkSize - 1) / _fileInfo.ChunkSize);
452-
var chunksFound = new HashSet<int>();
451+
var chunkCount = (_length + _fileInfo.ChunkSize - 1) / _fileInfo.ChunkSize;
452+
var chunksFound = new HashSet<long>();
453453
var foundExtraChunks = false;
454454
foreach (var chunk in _gridFS.Chunks.Find(query).SetFields(fields))
455455
{
456-
var n = chunk["n"].ToInt32();
456+
var n = chunk["n"].ToInt64();
457457
chunksFound.Add(n);
458458
if (n >= chunkCount)
459459
{
@@ -468,7 +468,7 @@ private void AddMissingChunks()
468468
}
469469

470470
BsonBinaryData zeros = null; // delay creating it until it's actually needed
471-
for (var n = 0; n < chunkCount; n++)
471+
for (var n = 0L; n < chunkCount; n++)
472472
{
473473
if (!chunksFound.Contains(n))
474474
{
@@ -480,15 +480,15 @@ private void AddMissingChunks()
480480
{
481481
{ "_id", ObjectId.GenerateNewId() },
482482
{ "files_id", _fileInfo.Id },
483-
{ "n", n },
483+
{ "n", (n < int.MaxValue) ? (BsonValue)BsonInt32.Create((int)n) : BsonInt64.Create(n) },
484484
{ "data", zeros }
485485
};
486486
_gridFS.Chunks.Insert(missingChunk);
487487
}
488488
}
489489
}
490490

491-
private void LoadChunk(int chunkIndex)
491+
private void LoadChunk(long chunkIndex)
492492
{
493493
if (_chunkIsDirty) { SaveChunk(); }
494494
var query = Query.And(Query.EQ("files_id", _fileInfo.Id), Query.EQ("n", chunkIndex));
@@ -526,7 +526,7 @@ private void LoadChunk(int chunkIndex)
526526
_chunkIndex = chunkIndex;
527527
}
528528

529-
private void LoadChunkNoData(int chunkIndex)
529+
private void LoadChunkNoData(long chunkIndex)
530530
{
531531
if (_chunkIsDirty) { SaveChunk(); }
532532
if (_chunk == null)
@@ -599,7 +599,7 @@ private void OpenTruncate()
599599

600600
private void SaveChunk()
601601
{
602-
var lastChunkIndex = (int)((_length + _fileInfo.ChunkSize - 1) / _fileInfo.ChunkSize) - 1;
602+
var lastChunkIndex = (_length + _fileInfo.ChunkSize - 1) / _fileInfo.ChunkSize - 1;
603603
if (_chunkIndex == -1 || _chunkIndex > lastChunkIndex)
604604
{
605605
var message = string.Format("Invalid chunk index {0}.", _chunkIndex);
@@ -629,7 +629,7 @@ private void SaveChunk()
629629
{
630630
{ "_id", _chunkId },
631631
{ "files_id", _fileInfo.Id },
632-
{ "n", _chunkIndex },
632+
{ "n", (_chunkIndex < int.MaxValue) ? (BsonValue)BsonInt32.Create((int)_chunkIndex) : BsonInt64.Create(_chunkIndex) },
633633
{ "data", data }
634634
};
635635
_gridFS.Chunks.Update(query, update, UpdateFlags.Upsert);

0 commit comments

Comments
 (0)