/// <exception cref="System.IO.IOException"></exception> private NGit.Storage.File.ReflogWriter Log(string refName, byte[] rec) { FilePath log = LogFor(refName); bool write = forceWrite || (IsLogAllRefUpdates() && ShouldAutoCreateLog(refName)) || log.IsFile(); if (!write) { return(this); } WriteConfig wc = GetRepository().GetConfig().Get(WriteConfig.KEY); FileOutputStream @out; try { @out = new FileOutputStream(log, true); } catch (FileNotFoundException err) { FilePath dir = log.GetParentFile(); if (dir.Exists()) { throw; } if (!dir.Mkdirs() && !dir.IsDirectory()) { throw new IOException(MessageFormat.Format(JGitText.Get().cannotCreateDirectory, dir)); } @out = new FileOutputStream(log, true); } try { if (wc.GetFSyncRefFiles()) { FileChannel fc = @out.GetChannel(); ByteBuffer buf = ByteBuffer.Wrap(rec); while (0 < buf.Remaining()) { fc.Write(buf); } fc.Force(true); } else { @out.Write(rec); } } finally { @out.Close(); } return(this); }
/// <summary>Flush ready buffer to persistent store.</summary> /// <remarks> /// Flush ready buffer to persistent store. currentBuffer is not flushed as it /// accumulates new log records while readyBuffer will be flushed and synced. /// </remarks> /// <exception cref="System.IO.IOException"/> protected internal override void FlushAndSync(bool durable) { if (fp == null) { throw new IOException("Trying to use aborted output stream"); } if (doubleBuf.IsFlushed()) { Log.Info("Nothing to flush"); return; } Preallocate(); // preallocate file if necessary doubleBuf.FlushTo(fp); if (durable && !shouldSkipFsyncForTests && !shouldSyncWritesAndSkipFsync) { fc.Force(false); } }
/// <summary>Write arbitrary data to the temporary file.</summary> /// <remarks>Write arbitrary data to the temporary file.</remarks> /// <param name="content"> /// the bytes to store in the temporary file. No additional bytes /// are added, so if the file must end with an LF it must appear /// at the end of the byte array. /// </param> /// <exception cref="System.IO.IOException"> /// the temporary file could not be written. The lock is released /// before throwing the underlying IO exception to the caller. /// </exception> /// <exception cref="Sharpen.RuntimeException"> /// the temporary file could not be written. The lock is released /// before throwing the underlying exception to the caller. /// </exception> public virtual void Write(byte[] content) { RequireLock(); try { if (fsync) { FileChannel fc = os.GetChannel(); ByteBuffer buf = ByteBuffer.Wrap(content); while (0 < buf.Remaining()) { fc.Write(buf); } fc.Force(true); } else { os.Write(content); } os.Close(); os = null; } catch (IOException ioe) { Unlock(); throw; } catch (RuntimeException ioe) { Unlock(); throw; } catch (Error ioe) { Unlock(); throw; } }