写入文本文件的空白 [英] Whitespace Written To Text File

查看:76
本文介绍了写入文本文件的空白的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个Silverlight应用程序需要读取和写入隔离存储文件的日期。在某个过程之后,我们将日期作为固定日期格式写入文本文件。在同一过程之前,我们阅读文本,并解析日期。直接听起来是
吧?


不幸的是,我们遇到的问题是写入文件的日期是空白而不是日期作为字符串。文本长度正确,但所有字符的值都为0(null)。这是
月和月的持续问题。我们自己无法重现这个问题。它每周只发生3-4次,大约有10-20个用户使用该应用程序。


这是一些写日期的代码:

 public static string DateFormat =" dd / MM / yyyy HH:mm:ss" ;; 


 private static bool WriteLastDateTime(DateTime lastDateTime,string fileName,out string currentDateString)
{
currentDateString = lastDateTime.ToRegionlessString();
返回IsolatedStorageUtilities.WriteFile(fileName,currentDateString);
}


 public static string ToRegionlessString(this DateTime date)
{
return date.ToString (日期格式);
}

以下是一些读取日期的代码:

 private static DateTime? GetLastDateTime(string fileName)
{
DateTime? retVal = null;
string dateString = null;
try
{
dateString = IsolatedStorageUtilities.ReadFileWithoutCatch(fileName);
Logger.Log(string.Format(" Successfully read file from file:{0},Text:{1}",fileName,dateString),LogMessageType.Information,typeof(OfflineUtilities).FullName,null) ;

if(!string.IsNullOrEmpty(dateString))
{
//用户ParseExact因此无论区域设置是什么,AU / NZ数据格式都按照使用DateFormat变量
retVal = DateTime.ParseExact(dateString,DateFormat,System.Globalization.CultureInfo.InvariantCulture);
Logger.Log(string.Format("成功解析最后一个日期为{0}",retVal),LogMessageType.Information,typeof(OfflineUtilities).FullName,null);
}
else
{
Logger.Log(string.Format("文件{0}中没有文字。",fileName),LogMessageType.Warning, typeof(OfflineUtilities).FullName,null);
返回null;
}
}
catch(exception ex)
{
Logger.Log($"尝试获取最后一个日期时发生错误。文件:{fileName日期格式必须是:{DateFormat}。日期文本是'{(dateString!= null?dateString:string.Empty)}'",ex);
}

返回retVal;
}

我们已经尝试了解决这个问题的所有方法,但仍然会发生。


起初我们认为这与区域设置有关,但我们通过明确格式化文本,并以不变文化的形式阅读文件来排除这一点。 / p>

我们认为它可能与Silverlight隔离文件存储API有关。因此,我复制了使用Windows API编写文件的所有代码。此方法使用具有提升信任的Windows API调用将文件写入独立存储之外:

 public static void WriteAllText(string fileName,string text)
{
uint lengthWritten;
NativeOverlapped overLap = new NativeOverlapped();
var stringBuilder = new StringBuilder(text);

//检查文件是否存在
if(WindowsAPICalls.PathFileExists(fileName))
{
//删除原始文件(如果存在)
if(!WindowsAPICalls.DeleteFile(fileName))
{
throw new Exception($"文件{fileName}无法访问以进行写入。它可能正由另一个进程使用。") ;
}
}

//创建用于写入
var fileHandle = WindowsAPICalls.CreateFile的文件句柄(fileName,0x40000000,0x00000001,IntPtr.Zero,4,0x00000080 ,IntPtr.Zero);
if(fileHandle == null)
{
throw new Exception($"文件{fileName}无法访问以进行写入。它可能正被另一个进程使用。" );
}

//将字符串生成器的缓冲区写入文件
if(!WindowsAPICalls.WriteFile(fileHandle,stringBuilder,(uint)text.Length,out lengthWritten,ref overLap))
{
抛出新的异常($"文件{fileName}无法写入文件。它可能被另一个进程使用。");
}

if(text.Length!= lengthWritten)
{
throw new Exception($"文本的长度是{text.Length}但是写入文件{fileName}的长度为{lengthWritten}");
}

if(!WindowsAPICalls.CloseHandle(fileHandle))
{
throw new Exception($"文件{fileName}已成功写入,但之后无法关闭文件句柄");
}
}

此方法正常运行,但我们发现偶尔会出现同样的问题。文本中写有空格。因此,它不会成为Silverlight文件编写API的问题。


我认为也许它可能会在DateTime.ToString()中出现错误。但是,我很确定情况并非如此,因为我们偶尔也会遇到将大块空白空间写入日志文件的情况。即发生同样的问题。


在写入文件之前,字符串数据似乎在内存中被破坏了。


我们是非常困难!





解决方案

嗨MelbourneDeveloper,


根据您的描述,此问题是随机发生的。随机问题很难找出导致此问题的原因。请尝试按照以下步骤排查此问题。


  1. 因为它发生在大约10-20个用户的计算机上,使用该应用程序,请总结一下是否有一些常见的功能。例如,相同的操作系统,在这些计算机上安装相同的程序等等。
  2. 将这些计算机与没有此问题的其他计算机进行比较,是否某些特定功能会导致此问题。
  3. 检查项目中的所有代码是否有其他代码读取/写入除上述代码之外的文本文件。
  4. 运行程序时请关闭其他程序,这可以帮助我们确定是否存在有任何其他程序操作您的文本文件。


最好的问候,

Weiwei


We have a Silverlight app that needs to read and write dates to an isolated storage file. After a certain process we write the date to a text file as a fixed date format . Before the same process we read the text, and parse the date. Sounds straight forward right?

Unfortunately, we're getting a problem where the date written to the file is full of whitespace instead of the date as a string. The text is the correct length, but all the characters have a value of 0 (null). This has been an ongoing problem for months and months. We can't recreate the problem ourselves. It only happens 3-4 times per week with about 10-20 users using the app.

Here is some code that writes the date:

public static string DateFormat = "dd/MM/yyyy HH:mm:ss";

        private static bool WriteLastDateTime(DateTime lastDateTime, string fileName, out string currentDateString)
        {
            currentDateString = lastDateTime.ToRegionlessString();
            return IsolatedStorageUtilities.WriteFile(fileName, currentDateString);
        }

        public static string ToRegionlessString(this DateTime date)
        {
            return date.ToString(DateFormat);
        }

Here is some code that reads the date:

        private static DateTime? GetLastDateTime(string fileName)
        {
            DateTime? retVal = null;
            string dateString = null;
            try
            {
                dateString = IsolatedStorageUtilities.ReadFileWithoutCatch(fileName);
                Logger.Log(string.Format("Successfully read text from file: {0}, Text: {1}", fileName, dateString), LogMessageType.Information, typeof(OfflineUtilities).FullName, null);

                if (!string.IsNullOrEmpty(dateString))
                {
                    //User ParseExact so that no matter what the regional settings are AU/NZ data formatting is used as per the DateFormat variable
                    retVal = DateTime.ParseExact(dateString, DateFormat, System.Globalization.CultureInfo.InvariantCulture);
                    Logger.Log(string.Format("Successfully parsed the last date as {0}", retVal), LogMessageType.Information, typeof(OfflineUtilities).FullName, null);
                }
                else
                {
                    Logger.Log(string.Format("There was no text in the file {0}.", fileName), LogMessageType.Warning, typeof(OfflineUtilities).FullName, null);
                    return null;
                }
            }
            catch (Exception ex)
            {
                Logger.Log($"An error occurred while attempting to get the last date. File: {fileName}. The date format must be: {DateFormat}. The date text was '{(dateString != null ? dateString : string.Empty)}'", ex);
            }

            return retVal;
        }

We've tried everything we can think of to solve this problem, but is still occurs.

At first we thought it was something to do with regional settings, but we ruled this out by explicitly formatting the text, and by reading the file in as invariant culture.

We thought it might be related to the Silverlight isolated file storage API. So, I duplicated all the code for writing the file with windows APIs. This method uses Windows API calls with elevated trust to write the file outside of isolated storage:

        public static void WriteAllText(string fileName, string text)
        {
            uint lengthWritten;
            NativeOverlapped overLap = new NativeOverlapped();
            var stringBuilder = new StringBuilder(text);

            //Check if the file exists
            if (WindowsAPICalls.PathFileExists(fileName))
            {
                //Delete the original file if it exists
                if (!WindowsAPICalls.DeleteFile(fileName))
                {
                    throw new Exception($"The file {fileName} could not be accessed for writing. It may be in use by another process.");
                }
            }

            //Create a file handle for writing
            var fileHandle = WindowsAPICalls.CreateFile(fileName, 0x40000000, 0x00000001, IntPtr.Zero, 4, 0x00000080, IntPtr.Zero);
            if (fileHandle == null)
            {
                throw new Exception($"The file {fileName} could not be accessed for writing. It may be in use by another process.");
            }

            //Write the buffer of the string builder to file
            if (!WindowsAPICalls.WriteFile(fileHandle, stringBuilder, (uint)text.Length, out lengthWritten, ref overLap))
            {
                throw new Exception($"The file {fileName} could not be written to file. It may be in use by another process.");
            }

            if (text.Length != lengthWritten)
            {
                throw new Exception($"The length of the text was {text.Length} but the length written to the file {fileName} was {lengthWritten}");
            }

            if (!WindowsAPICalls.CloseHandle(fileHandle))
            {
                throw new Exception($"The file {fileName} was successfully written to, but the file handle could not be closed afterwards");
            }
        }

This method works correctly, but what we found is that the same issue occurs occasionally. The text is written with whitespace in it. So, it can't be a problem with the Silverlight file writing API.

I thought that perhaps it could get a bug in DateTime.ToString(). But, I'm pretty sure that this is not the case because we also occasionally get cases where a big chunk of white space is written to a log file. I.e. the same problem occurs.

It almost seems as though the string data is getting corrupted in memory before it is being written to file.

We are very stuck!

解决方案

Hi MelbourneDeveloper,

According to your description, this problem is occurs random. The random problem is very difficult to find out what causes this issue. Please try with following steps to troubleshoot this problem.

  1. Since it happens on about 10-20 users' computer using the app, please summarize whether they have some common features. For example, the same OS, install a same program on these computers and so on.
  2. Compare these computers with other computers that don't have this problem, whether some specific features causes this issue.
  3. Check all code in your project whether there has other code read/write the text file except above code.
  4. Please close other programs when running your program, which can help us make sure whether there has any other program operate your text file.

Best Regards,
Weiwei


这篇关于写入文本文件的空白的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆