1

.jrn ファイル (ATM マシン内) から更新されたデータを読み取り、そのテキストを一時テキスト ファイル "tempfile.txt" にコピーする Windows アプリケーションを開発しました。

「tempfile.txt」を読み取り、その内容を CCTV カメラに表示する「POS Text Sender」と呼ばれる別のサードパーティ アプリケーションがあります。

問題は、tempfile に何かを直接入力すると、POS アプリケーションがそれを読み取ることですが、アプリケーションがテキストを「tempfile」に書き込むと、tempfile の .jrn ファイルと同じ内容を見ることができますが、そうではありません。新しく生成されたファイルから tempfile にデータがコピーされるたびに、POS アプリケーションに反映されます。新しく生成されたファイルから最初のデータが tempfile にコピーされた後に POS Text Sender を再起動すると、POS Text Sender は、新しく作成されたファイルのコンテンツが書き込まれるまでコンテンツを表示します。一時ファイルへ

私のアプリケーション コードは、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: コピーウェアハウスをこれに変更して、問題が解決しないことを確認できますか:

         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

1 つの違いは、アプリケーションが tempfile.txt に直接書き込むのではなく、別のファイルに書き込み、そのファイルを tempfile.txt にコピーすることです。

于 2012-08-26T11:36:36.027 に答える