1

我开发了一个 Windows 应用程序,它将从 .jrn 文件(在 ATM 机中)读取更新的数据,并将文本复制到临时文本文件“tempfile.txt”。

还有另一个名为“POS Text Sender”的第三方应用程序,它读取“tempfile.txt”并将其内容显示在闭路电视摄像机中。

问题是,如果我直接在 tempfile 中键入内容,POS 应用程序会读取它,但如果我的应用程序将文本写入“tempfile”,我可以在 tempfile 中看到与 .jrn 文件中相同的内容,但事实并非如此当数据从新生成的文件复制到临时文件时反映在 POS 应用程序中。如果在从新生成的文件复制到临时文件的第一个数据后重新启动 POS 文本发送器,POS 文本发送器将显示内容直到新创建的文件中的内容被写入到临时文件

我的应用程序代码正在使用 StreamReader 读取 .jrn 文件并将其分配给字符串变量,然后使用 StreamWriter 将其写入临时文件。在文件上手动键入文本和 .NET StreamWriter 将文本写入文件有什么区别?

代码:

 DateTime LastChecked = DateTime.Now;
 try
 {
     string[] files = System.IO.Directory.GetFiles(@"C:\Test", "*.jrn", System.IO.SearchOption.AllDirectories);

     foreach (string file in files)
     {
         if (!fileList.Contains(file))
         {
             currentfilename = file;
             fileList.Add(file);
             copywarehouse(file);
             //do_some_processing();
             try
             {
                 // Create an instance of StreamReader to read from a file.
                 // The using statement also closes the StreamReader.
                 using (StreamReader sr = new StreamReader(file))
                 {
                     currentcontent=sr.ReadToEnd();
                     // Read and display lines from the file until the end of
                     //// the file is reached.
                     //while ((currentcontent = sr.ReadLine()) != null)
                     //{

                     //}
                     sr.Close();
                     //sr.Dispose();
                 }
             }
             catch (Exception)
             {
                 // Let the user know what went wrong.

             }
         }
     }

     //checking
     try
     {
         using (StreamReader sr = new StreamReader(currentfilename))
         {
             string currentfilecontent = sr.ReadToEnd();
             sr.Close();
             //sr.Dispose();
             if (currentfilecontent!=currentcontent)
             {
                 if (currentfilecontent.Contains(currentcontent))
                 {
                     string originalcontent = currentfilecontent.Substring(currentcontent.Length);
                     System.IO.StreamWriter filenew = new System.IO.StreamWriter(@"C:\Test\tempfile.txt");

                     filenew.WriteLine(originalcontent);
                     filenew.Close();
                     currentcontent = currentfilecontent;
                 }
             }
         }
     }
     catch (Exception)
     {
         // Let the user know what went wrong.
     }

copywarehouse方法:

 private void copywarehouse(string filename)
 {
    string sourcePath = @"C:\Test";
    string targetPath = @"C:\Test";
    try
    {
       string sourceFile = System.IO.Path.Combine(sourcePath, filename);
       string destFile = System.IO.Path.Combine(targetPath, "tempfile.txt");
       System.IO.File.Copy(sourceFile, destFile, true);
    }
    catch (Exception)
    {

    }
}
4

3 回答 3

3

您可以检查以下内容:

  1. 生成的文件编码是否与手动创建的文件相同?(即 UTF-8/ANSI)。
  2. 您是否在不断刷新 streamWriter 的缓冲区?或者将 StreamWriter 的 AutoFlush 属性设置为 true。
  3. StreamWriter 是否使用 WriteLock 打开且不允许读取?在这种情况下,其他应用程序可能无法打开您的临时文件进行读取访问。

编辑:

此外,在您发布的代码中,您将 tempFile 数据与当前数据进行比较,如果 tempFile 数据比当前数据新,则您正在附加临时文件,我认为反之亦然。

主要变化:

using (StreamWriter filenew = new StreamWriter(fileDetail.TempFileName, true, Encoding.ASCII))
                                {
                                    filenew.WriteLine(newContent);
                                }

要知道正确的编码,只需创建一个新的 tempFile,在编辑器中写一些东西并保存它。在记事本中打开文件并执行“另存为”。这将在底部显示当前编码。在 .NET 代码中设置该编码。

如果这不起作用尝试(由 shr 推荐):

using (StreamWriter filenew = new StreamWriter(fileDetail.TempFileName, true, Encoding.ASCII))
                                {
                                    filenew.Write(newContent + "\r\n");
                                }

长版:(可能与您的代码有点不同):

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime LastChecked = DateTime.Now;

            IDictionary<string, FileDetails> fileDetails = new Dictionary<string, FileDetails>(StringComparer.OrdinalIgnoreCase);
            IList<string> tempFileList = new List<string>();

            try
            {
                string[] files = System.IO.Directory.GetFiles(@"C:\Test", "*.jrn", System.IO.SearchOption.AllDirectories);

                foreach (string file in files)
                {
                    string currentfilename = file;
                    string currentcontent = string.Empty;

                    if (!fileDetails.Keys.Contains(file))
                    {
                        fileDetails[file] = new FileDetails(copywarehouse(file));
                        //do_some_processing();
                    }

                    try
                    {
                        using (StreamReader sr = new StreamReader(file))
                        {
                            currentcontent = sr.ReadToEnd();
                        }
                    }
                    catch (Exception)
                    {
                        // Let the user know what went wrong.
                    }

                    fileDetails[file].AddContent(currentcontent);
                }

                //TODO: Check using the file modified time. Avoids unnecessary reading of file.
                foreach (var fileDetail in fileDetails.Values)
                {
                    //checking
                    try
                    {
                        string tempFileContent = string.Empty;
                        string currentcontent = fileDetail.GetContent();

                        using (StreamReader sr = new StreamReader(fileDetail.TempFileName))
                        {
                            tempFileContent = sr.ReadToEnd();
                            sr.Close();
                        }

                        if (!(0 == string.Compare(tempFileContent, currentcontent)))
                        {
                            if (currentcontent.Contains(tempFileContent))
                            {
                                string newContent = tempFileContent.Substring(currentcontent.Length);

                                using (StreamWriter filenew = new StreamWriter(fileDetail.TempFileName, true, Encoding.ASCII))
                                {
                                    filenew.WriteLine(newContent);
                                }
                            }
                        }
                    }
                    catch (Exception)
                    {
                        // Let the user know what went wrong.
                    }

                }
            }
            catch (Exception)
            {
            }
        }

        private static string copywarehouse(string filename)
        {
            string sourcePath = @"C:\Test";
            string targetPath = @"C:\Test";

            string sourceFile = System.IO.Path.Combine(sourcePath, filename);
            string destFile = System.IO.Path.Combine(targetPath, filename+ "tempfile.txt");

            try
            {
                System.IO.File.Copy(sourceFile, destFile, true);
            }
            catch (Exception)
            {
            }

            return destFile;
        }

        internal class FileDetails
        {
            public string TempFileName { get; private set; }
            private StringBuilder _content;

            public FileDetails(string tempFileName)
            {
                TempFileName = tempFileName;
                _content = new StringBuilder();
            }

            public void AddContent(string content)
            {
                _content.Append(content);
            }

            public string GetContent()
            {
                return _content.ToString();
            }
        }
    }
}

编辑 2: 您可以将 copywarehouse 更改为此并查看问题仍然存在:

         private void copywarehouse(string filename)
        {
            const string sourcePath = @"C:\Test";
            const string targetPath = @"C:\Test";
            try
            {
                string sourceFile = Path.Combine(sourcePath, filename);
                string destFile = Path.Combine(targetPath, "tempfile.txt");


                string currentcontent;
                using (var sr = new StreamReader(sourceFile))
                {
                    currentcontent = sr.ReadToEnd();
                }

                using (var wr = new StreamWriter(destFile, false, Encoding.ASCII))
                {
                    wr.WriteLine(currentcontent);
                }
            }
            catch (Exception)
            {

            }
        }
于 2012-08-26T11:21:41.723 回答
2

这很可能是 CR+LF 问题。POS 期望文件的行结尾为 CR+LF(回车 (0x0D) + 新行 (0x0A))组合。

filenew.WriteLine(originalcontent)仅附加换行符。我认为,当您键入时,您的编辑器必须为所有行尾创建 CR+LF 组合。

我建议你试试filenew.Write( originalcontent + "\r\n");

于 2012-08-26T12:19:19.173 回答
1

一个区别是您的应用程序不会直接写入 tempfile.txt,而是写入另一个文件,然后将该文件复制到 tempfile.txt。

于 2012-08-26T11:36:36.027 回答