我需要从FileStream对象创建一个StreamWriter并附加一些文本 文件。假设正在使用的FileStream对象是使用FileMode.OpenOrCreate和FileAccess.ReadWrite创建的。我有:
using (FileStream fs = GetCurrentFileStream())
{
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine("StringToAppend");
sw.Flush();
}
然而,这只是从头开始覆盖文件。如何移动到文件末尾?在创建FileStream之后,是否有办法将FileMode更改为Append,将FileAccess更改为Write?
编辑:如上所述,我需要使用FileStream对象来完成此操作。 Open existing file, append a single line的答案假设我可以从我没有的文件路径创建一个新的StreamWriter。
编辑2:添加截断版本的GetCurrentFileStream()。
public static FileStream GetCurrentFileStream()
{
String fileName = getFileName();
FileStream fs = OpenFileWhenAvailable(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
}
public static FileStream OpenFileWhenAvailable(String fileName, FileMode fileMode, FileAccess fileAccess, FileShare fileShare)
{
int tries = 0;
int timeout = 10 * 1000;
while (true)
{
tries++;
try
{
return new FileStream(fileName, fileMode, fileAccess, fileShare);
}
catch (IOException ex)
{
if (tries * 100 > timeout)
{
return null;
}
else
{
System.Threading.Thread.Sleep(100);
}
}
}
}
GetCurrentFileStream用于多个不同的上下文,因此不能直接更改FileMode和FileAccess。我不希望仅针对这种情况创建单独版本的GetCurrentFileStream,这就是为什么我要问是否有一种方法可以跳转到流的末尾并在已经创建FileStream对象时附加一个字符串。
答案 0 :(得分:7)
如果我理解正确,您希望将您的行追加到创建的文件中:
using (FileStream fs = GetCurrentFileStream())
{
StreamWriter sw = new StreamWriter(fs, true);
sw.WriteLine("StringToAppend");
sw.Flush();
}
使用StreamWriter构造函数的这个重载,您可以选择是附加文件还是覆盖它。
如果您展示方法GetCurrentStream()
的实施方式,那将非常酷:
using (FileStream fileStream = new FileStream(fileName,FileMode.Append, FileAccess.Write))
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine(something);
}
<强>更新强>:
using (FileStream fs = GetCurrentFileStream())
{
StreamWriter sw = new StreamWriter(fs);
long endPoint=fs.Length;
// Set the stream position to the end of the file.
fs.Seek(endPoint, SeekOrigin.Begin);
sw.WriteLine("StringToAppend");
sw.Flush();
}
答案 1 :(得分:0)
如果你真的很想,你可以这么做......
static int iMaxLogLength = 15000;
static int iTrimmedLogLength = -2000;
static public void writeToFile2(string strMessage, string strLogFileDirectory, int iLogLevel)
{
string strFile = strLogFileDirectory + "log.log";
try
{
FileInfo fi = new FileInfo(strFile);
Byte[] bytesRead = null;
if (fi.Length > iMaxLogLength)
{
using (BinaryReader br = new BinaryReader(File.Open(strFile, FileMode.Open)))
{
// Go to the end of the file and backup some
br.BaseStream.Seek(iTrimmedLogLength, SeekOrigin.End);
// Read that.
bytesRead = br.ReadBytes((-1 * iTrimmedLogLength));
}
}
byte[] newLine = System.Text.ASCIIEncoding.ASCII.GetBytes(Environment.NewLine);
FileStream fs = null;
if (fi.Length < iMaxLogLength)
fs = new FileStream(strFile, FileMode.Append, FileAccess.Write, FileShare.Read);
else
fs = new FileStream(strFile, FileMode.Create, FileAccess.Write, FileShare.Read);
using (fs)
{
if (bytesRead != null)
{
fs.Write(bytesRead, 0, bytesRead.Length);
fs.Write(newLine, 0, newLine.Length);
Byte[] lineBreak = Encoding.ASCII.GetBytes("### " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " *** *** *** New Log Start Position *** *** *** *** ###");
fs.Write(lineBreak, 0, lineBreak.Length);
fs.Write(newLine, 0, newLine.Length);
}
Byte[] sendBytes = Encoding.ASCII.GetBytes(strMessage);
fs.Write(sendBytes, 0, sendBytes.Length);
fs.Write(newLine, 0, newLine.Length);
}
}
catch (Exception ex)
{
; // Write to event or something
}
}