private Stream CacheAndCreateEntryStream(string filename, string entryName) { Stream stream = null; var dataStream = _dataProvider.Fetch(filename); if (dataStream != null) { try { var newItem = new CachedZipFile(dataStream, DateTime.UtcNow, filename); // here we don't need to lock over the cache item // because it was still not added in the cache stream = CreateEntryStream(newItem, entryName, filename); if (!_zipFileCache.TryAdd(filename, newItem)) { // some other thread could of added it already, lets dispose ours newItem.Dispose(); } } catch (Exception exception) { if (exception is ZipException || exception is ZlibException) { Log.Error("ZipDataCacheProvider.Fetch(): Corrupt zip file/entry: " + filename + "#" + entryName + " Error: " + exception); } else { throw; } } } return(stream); }
/// <summary> /// Cache a Zip /// </summary> /// <param name="filename">Zip to cache</param> /// <param name="cachedZip">The resulting CachedZipFile</param> /// <returns></returns> private bool Cache(string filename, out CachedZipFile cachedZip) { cachedZip = null; var dataStream = _dataProvider.Fetch(filename); if (dataStream != null) { try { cachedZip = new CachedZipFile(dataStream, DateTime.UtcNow, filename); if (!_zipFileCache.TryAdd(filename, cachedZip)) { // some other thread could of added it already, lets dispose ours cachedZip.Dispose(); return(_zipFileCache.TryGetValue(filename, out cachedZip)); } return(true); } catch (Exception exception) { if (exception is ZipException || exception is ZlibException) { Log.Error("ZipDataCacheProvider.Fetch(): Corrupt zip file/entry: " + filename + " Error: " + exception); } else { throw; } } dataStream.Dispose(); } return(false); }
/// <summary> /// Does not attempt to retrieve any data /// </summary> public Stream Fetch(string key) { string entryName = null; // default to all entries var filename = key; var hashIndex = key.LastIndexOf("#", StringComparison.Ordinal); if (hashIndex != -1) { entryName = key.Substring(hashIndex + 1); filename = key.Substring(0, hashIndex); } // handles zip files if (filename.GetExtension() == ".zip") { Stream stream = null; // scan the cache once every 3 seconds if (_lastCacheScan == DateTime.MinValue || _lastCacheScan < DateTime.Now.AddSeconds(-3)) { CleanCache(); } try { CachedZipFile existingEntry; if (!_zipFileCache.TryGetValue(filename, out existingEntry)) { var dataStream = _dataProvider.Fetch(filename); if (dataStream != null) { try { var newItem = new CachedZipFile(dataStream, filename); stream = CreateStream(newItem, entryName, filename); if (!_zipFileCache.TryAdd(filename, newItem)) { newItem.Dispose(); } } catch (Exception exception) { if (exception is ZipException || exception is ZlibException) { Log.Error("ZipDataCacheProvider.Fetch(): Corrupt zip file/entry: " + filename + "#" + entryName + " Error: " + exception); } else { throw; } } } } else { try { lock (existingEntry) { stream = CreateStream(existingEntry, entryName, filename); } } catch (Exception exception) { if (exception is ZipException || exception is ZlibException) { Log.Error("ZipDataCacheProvider.Fetch(): Corrupt zip file/entry: " + filename + "#" + entryName + " Error: " + exception); } else { throw; } } } return(stream); } catch (Exception err) { Log.Error(err, "Inner try/catch"); stream?.DisposeSafely(); return(null); } } else { // handles text files return(_dataProvider.Fetch(filename)); } }