【问题标题】:Why the variable FileStream writer is null?为什么变量 FileStream writer 为空?
【发布时间】:2017-02-10 04:26:40
【问题描述】:

我在两种情况下使用 writer。

private void downloadFile(Int32 fileNr)
        {
            FileStream writer = null;
            m_currentFileSize = 0;
            fireEventFromBgw(Event.FileDownloadAttempting);

            FileInfo file = this.Files[fileNr];
            FileInfo fileFirstDateTime = this.Files[0];
            FileInfo fileLastDateTime = this.Files[19];
            Int64 size = 0;

            Byte[] readBytes = new Byte[this.PackageSize];
            Int32 currentPackageSize;
            System.Diagnostics.Stopwatch speedTimer = new System.Diagnostics.Stopwatch();
            Int32 readings = 0;
            Exception exc = null;

            if (form1.checkBox1.Text == "Download satellite images")
            {
                LocalDirectorySettings(file, writer);
            }
            else
            {
                writer = new FileStream(this.LocalDirectory + "\\" + file.Name, System.IO.FileMode.Create);
            }


            HttpWebRequest webReq;
            HttpWebResponse webResp = null;

            try
            {
                webReq = (HttpWebRequest)System.Net.WebRequest.Create(this.Files[fileNr].Path);
                webResp = (HttpWebResponse)webReq.GetResponse();

                size = webResp.ContentLength;
            }
            catch (Exception ex) { exc = ex; }

            m_currentFileSize = size;
            fireEventFromBgw(Event.FileDownloadStarted);

            if (exc != null)
            {
                bgwDownloader.ReportProgress((Int32)InvokeType.FileDownloadFailedRaiser, exc);
            }
            else
            {
                m_currentFileProgress = 0;
                while (m_currentFileProgress < size && !bgwDownloader.CancellationPending)
                {
                    while (this.IsPaused) { System.Threading.Thread.Sleep(100); }

                    speedTimer.Start();

                    currentPackageSize = webResp.GetResponseStream().Read(readBytes, 0, this.PackageSize);

                    m_currentFileProgress += currentPackageSize;
                    m_totalProgress += currentPackageSize;
                    fireEventFromBgw(Event.ProgressChanged);
                    try
                    {
                        writer.Write(readBytes, 0, currentPackageSize);
                    }
                    catch(Exception eee)
                    {
                        string myeee = eee.ToString();
                    }
                    readings += 1;

                    if (readings >= this.StopWatchCyclesAmount)
                    {
                        m_currentSpeed = (Int32)(this.PackageSize * StopWatchCyclesAmount * 1000 / (speedTimer.ElapsedMilliseconds + 1));
                        speedTimer.Reset();
                        readings = 0;
                    }
                }

                speedTimer.Stop();
                writer.Close();
                webResp.Close();
                if (!bgwDownloader.CancellationPending) { fireEventFromBgw(Event.FileDownloadSucceeded); }
            }
            fireEventFromBgw(Event.FileDownloadStopped);
        }

在这部分中,如果它执行 else 部分,它工作正常:

if (form1.checkBox1.Text == "Download satellite images")
            {
                LocalDirectorySettings(file, writer);
            }
            else
            {
                writer = new FileStream(this.LocalDirectory + "\\" + file.Name, System.IO.FileMode.Create);
            }

如果它在做这条线:没关系:

writer = new FileStream(this.LocalDirectory + "\\" + file.Name, System.IO.FileMode.Create);

但是一旦我更改了复选框,它就会执行 IF 的第一部分:

LocalDirectorySettings(file, writer);

这是 LocalDirectorySettings 方法代码:

public void LocalDirectorySettings(FileInfo file, FileStream writer)
        {
            try
            {
                var startIndex = file.Path.IndexOf("region=") + "region=".Length;
                var length = file.Path.IndexOf("&", startIndex) - startIndex;
                var code = file.Path.Substring(startIndex, length);
                var countryName = form1.codeToFullNameMap[code];

                string firstDT = ParseDateTime(this.Files[0]);
                string lastDT = ParseDateTime(this.Files[19]);
                string subDirectoryDT = firstDT + "---" + lastDT;

                string countryPath = Path.Combine(form1.mainPath, countryName);
                LocalDirectory = countryPath + "\\" + subDirectoryDT;

                if (!Directory.Exists(LocalDirectory))
                {
                    Directory.CreateDirectory(LocalDirectory);
                }

                string fileName = this.LocalDirectory + "\\" + "test.png"; //file.Name + "---" + countFilesNames++.ToString("D6") + ".png";
                writer = new FileStream(fileName, System.IO.FileMode.Create); // Set a breakpoint here.
            }
            catch (Exception err)
            {
                string ggg = err.ToString();
            }
        }

即使在 LocalDirectorySettings 方法中有一行带有 writer 实例的行:

writer = new FileStream(fileName, System.IO.FileMode.Create);

我正在使用一个断点,它确实到达了 LocalDirectorySettings 中的这一行,但是当它继续到该部分时:

try
                    {
                        writer.Write(readBytes, 0, currentPackageSize);
                    }
                    catch(Exception eee)
                    {
                        string myeee = eee.ToString();
                    }

到了 catch 部分,说 writer 为空。并且使用断点我看到 writer 为空。

为什么当它到达 LocalDirectorySettings 之后,作者是空的?

【问题讨论】:

    标签: c# .net winforms


    【解决方案1】:

    设置参数,LocalDirectorySettings()方法中名为writer的局部变量,对other局部变量没有影响,也叫writer,在调用者中找到,@987654324 @。

    我强烈建议反对使用类字段来共享此对象(如其他答案中所建议的那样)。没有理由这样做,这样做只会让你的课堂变得混乱。相反,要么通过引用传递参数,要么更好地让LocalDirectorySettings() 方法返回对象。例如:

    void downloadFile(int fileNr)
    {
        FileStream writer;
    
        //...
    
        if (form1.checkBox1.Text == "Download satellite images")
        {
            writer = LocalDirectorySettings(file);
        }
        else
        {
            writer = new FileStream(this.LocalDirectory + "\\" + file.Name, System.IO.FileMode.Create);
        }
    
        //...
    }
    
    public FileStream LocalDirectorySettings(FileInfo file)
    {
        try
        {
            //...
    
            string fileName = this.LocalDirectory + "\\" + "test.png"; //file.Name + "---" + countFilesNames++.ToString("D6") + ".png";
            return new FileStream(fileName, System.IO.FileMode.Create);
        }
        catch (Exception err)
        {
            string ggg = err.ToString();
            throw; // you don't actually handle the exception, so rethrowing
                   // is the appropriate action here. Your only alternative
                   // would be to return "null" and have the caller check for
                   // that return value explicitly.
        }
    }
    

    【讨论】:

      【解决方案2】:

      LocalDirectorySettings 中,您正在为函数参数分配一个新的FileStream。这不会影响 downloadFile 中的 writer 变量。

      writer 设为成员变量,以便两个方法可以共享它。

      FileStream writer = null;
      private void downloadFile(Int32 fileNr)
      {
          // Do stuff with writer
      }
      
      public void LocalDirectorySettings(FileInfo file)
      {
          // Do stuff with writer
      }
      

      【讨论】:

        猜你喜欢
        • 2021-03-13
        • 2012-12-23
        • 2015-09-05
        • 2018-01-16
        • 2015-12-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多