简体   繁体   English

C#文件I / O效率

[英]C# File I/O Efficiency

I have done a homework assignment, here is the problem statement: 我已经完成了一项作业,这是问题陈述:

Your program should work as follows: 您的程序应如下工作:

  1. Ask the user to give you a file name. 要求用户给您一个文件名。 Get the file name and save it. 获取文件名并保存。
  2. Open the file. 打开文件。
  3. From the file read a temperature and a wind speed. 从文件中读取温度和风速。 Both values should be stored in variables declared as double. 两个值都应存储在声明为double的变量中。 The file is a text file. 该文件是文本文件。 Each line of the file contains a temperature and a wind speed value. 文件的每一行都包含温度和风速值。
  4. Calculate the wind chill factor using a programmer written method, and display the result in the form: 使用程序员编写的方法计算风冷系数,并以以下形式显示结果:

    For t = temperature from file and v = wind speed from file Wind chill index = calculated result degrees Fahrenheit. 对于t =来自文件的温度和v =来自文件的风速风寒指数=计算结果华氏度。

    Show all numbers with two digits after the decimal point. 用小数点后两位显示所有数字。 (Remember-no magic numbers!) (记住,没有魔术数字!)

  5. Repeat these steps until an end of file is encountered. 重复这些步骤,直到遇到文件结尾。

I have completed the assignment, my code is below, I was just wondering if there was any way to make it more efficient, or if there are some different and creative ways to accomplish this problem, I already turned this in and got 50/50, but I'm just curious as to how some of you advanced and skilled programmers would approach this problem. 我已经完成了任务,代码在下面,我只是想知道是否有任何方法可以使它更有效,或者是否有其他一些创造性的方法来解决此问题,所以我已经把它搞定了,得出50/50 ,但我只是好奇你们中的一些高级和熟练的程序员如何解决这个问题。

using System;
using System.IO;

class Program
{
    // declare constants to use in wind chill factor equation - no magic numbers
    const double FIRST_EQUATION_NUMBER = 35.74;
    const double SECOND_EQUATION_NUMBER = 0.6215;
    const double THIRD_EQUATION_NUMBER = 35.75;
    const double FOURTH_EQUATION_NUMBER = 0.4275;
    const double EQUATION_EXPONENT = 0.16;
    const int DEGREE_SYMBOL_NUMBER = 176;

    static void Main()
    {
        // declare and initialize some variables
        string filePath = "";
        string line = "";
        double temperature = 0.0;
        double windSpeed = 0.0;
        double windChillFactor = 0.0;
        char degreeSymbol = (char)DEGREE_SYMBOL_NUMBER;

        // ask user for a file path
        Console.Write("Please enter a valid file path: ");
        filePath = Console.ReadLine();

        // create a new instance of the StreamReader class
        StreamReader windChillDoc = new StreamReader(@filePath);

        // start the read loop
        do 
        {
            // read in a line and save it as a string variable
            line = windChillDoc.ReadLine();

            // is resulting string empty? If not, continue execution
            if (line != null)
            {
                string[] values = line.Split();
                temperature = double.Parse(values[0]);
                windSpeed = double.Parse(values[1]);

                windChillFactor = WindChillCalc(temperature, windSpeed);

                Console.WriteLine("\nFor a temperature {0:f2} F{1}", temperature, degreeSymbol);
                Console.WriteLine("and a wind velocity {0:f2}mph", windSpeed);
                Console.WriteLine("The wind chill factor = {0:f2}{1}\n", windChillFactor, degreeSymbol);
            }
        } while (line != null);

        windChillDoc.Close();

        Console.WriteLine("\nReached the end of the file, press enter to exit this program");

        Console.ReadLine();
    }//End Main()

    /// <summary>
    /// The WindChillCalc Method
    /// Evaluates a wind chill factor at a given temperature and windspeed
    /// </summary>
    /// <param name="temperature">A given temperature</param>
    /// <param name="ws">A given windspeed</param>
    /// <returns>The calculated wind chill factor, as a double</returns>
    static double WindChillCalc(double temperature, double ws)
    {
        double wci = 0.0;
        wci = FIRST_EQUATION_NUMBER + (SECOND_EQUATION_NUMBER * temperature) - (THIRD_EQUATION_NUMBER * (Math.Pow(ws, EQUATION_EXPONENT))) + (FOURTH_EQUATION_NUMBER * temperature * (Math.Pow(ws, EQUATION_EXPONENT)));
        return wci;
    }
}//End class Program 

Feel free to tell me what you think of it. 随时告诉我您的想法。

Your way looks good, but: 您的方法看起来不错,但是:

  • It would look nicer if you used PascalCase for the constants, as that's what coding conventions for c# use. 如果将PascalCase用作常量,则效果会更好,因为这就是c#使用的编码约定。
  • you should wrap the StreamReader in a using statement, so it gets properly disposed once you're done. 您应该将StreamReader包装在using语句中,以便在完成后将其正确处理。
  • You should probably also wrap it in a try block (and a catch to properly handle the exception) to make sure that you don't get a FileNotFound exception. 您可能还应该将其包装在try块中(并添加一个catch以正确处理该异常),以确保没有收到FileNotFound异常。
  • It's probably a better idea to structure your while loop the following way: 用以下方式构造while循环可能是一个更好的主意:

while((line = windChillDoc.ReadLine()) != null) { ... } [Darn formatting won't work right!] while((line = windChillDoc.ReadLine()) != null) { ... } [Darn格式无法正常工作!]

Other than that though, i wouldn't know as i'm not familiar with weather calculations :) 除此之外,我不知道,因为我对天气计算不熟悉:)

You're not going to get much zippier than that for file IO in C#. 您不会获得比C#中的文件IO更高的zippier。 Depending on the size of the data set it may be worth using a buffered reader, but for sufficiently small files, it's just not worth it. 根据数据集的大小,使用缓冲的读取器可能值得,但是对于足够小的文件,这是不值得的。 I'd leave it as-is. 我会保持原样。

Most of your comments are extraneous. 您的大部分评论都是多余的。 The code should tell you how...the comments should tell you why. 代码应告诉您如何...注释应告诉您原因。

较小的nitpick,但是如果您使用的是英语方法名称,则“ WindChillCalc”应为“ CalcWindChill”(动词排在最前面)。

string filePath = "";
...
filePath = Console.ReadLine();

Don't initialize with values that are never used; 不要使用从未使用过的值进行初始化; and keep declaration and initialization close together: 并保持声明和初始化在一起:

string filePath = Console.ReadLine();

using has been mentioned - but don't use @ unnecessarily: 提到了using -但不要不必要地使用@

new StreamReader(@filePath);

should be just: 应该只是:

new StreamReader(filePath);

Personally, I'd use LINQ for the line-reader, but that is just me ;-p 就个人而言,我将LINQ用于行读取器,但这只是我自己; -p

Why the do/while ? 为什么要/同时做 In your do you check for null. 在你你检查空。 In your while you check for null. 在您检查期间是否为空。 Why not just make it a while statement? 为什么不作一会儿发言?

string line;
while((line = windChillDoc.ReadLine()) != null)
{
    //Logic
}

EDIT : Fixed the compilation error. 编辑 :修复了编译错误。 Funny thing was I had that originally. 有趣的是,我本来就是这样。 This Rich Text Box needs a compiler! 这个Rich Text Box需要编译器! :P :P

Although not really relating to performance (the main question) 尽管与绩效并没有真正的关系(主要问题)

IMO: 海事组织:

const double FIRST_EQUATION_NUMBER = 35.74;
const double SECOND_EQUATION_NUMBER = 0.6215;
const double THIRD_EQUATION_NUMBER = 35.75;
const double FOURTH_EQUATION_NUMBER = 0.4275;
const double EQUATION_EXPONENT = 0.16;

isn't much better than a magic number. 没有比魔术数字好多少了。 Looking at that I have no idea what FIRST_EQUATION_NUMBER is used for other than in an equation somewhere, and I can't tell that they are in the same equation or you have four equations which use different numbers? 看着我不知道FIRST_EQUATION_NUMBER除了在某处的方程式中还用于什么FIRST_EQUATION_NUMBER ,我不知道它们在同一个方程式中还是您有四个使用不同数字的方程式? They could also be put into the actual method as thats the only place they are used. 也可以将它们放到实际方法中,因为那是它们被使用的唯一位置。

I would change degreeSymbol to a const rather than working it from a const int later. 我将把degreeSymbol更改为const,而不是以后从const int使用它。

const char DEGREE_SYMBOL = (char)176;

If you're getting marked on style etc. then there's a couple extremely minor things 如果您在样式等方面被打上标记,那么有几件非常小的事情

  • Initializing doubles to 0.0 is redundant. 将double初始化为0.0是多余的。
  • string.Empty is preferred instead of "" 首选string.Empty而不是“”
  • Your windchill method can be changed to simply (though, during compilation, I think that wci will be optimized out - so it's functionally the same): 您的windchill方法可以更改为简单方法(不过,在编译过程中,我认为wci将被优化-因此功能上相同):

(changed formatting for SO readability) (为了便于阅读,更改了格式)

static double WindChillCalc(double temperature, double ws)
{
    return FIRST_EQUATION_NUMBER + 
        (SECOND_EQUATION_NUMBER * temperature) - 
        (THIRD_EQUATION_NUMBER * (Math.Pow(ws, EQUATION_EXPONENT))) + 
        (FOURTH_EQUATION_NUMBER * temperature * (Math.Pow(ws, EQUATION_EXPONENT)));
}

In little academic programs like this, unless you do something really dumb, performance will not be an issue. 在像这样的小型学术程序中,除非您做一些真正愚蠢的事情,否则性能不会成为问题。 A simple way to tell if performance is an issue is to ask the question: "Does it make me wait?" 判断性能是否成问题的一种简单方法是问一个问题:“它让我等待吗?”

If there were an enormous amount of input, I would ask who's providing the input and who's reading the output. 如果有大量输入,我会问谁在提供输入,谁在阅读输出。 That would tell me if I could do the I/O in binary rather than text, because as it is, by far the bulk of the processing will be in the conversion of text into numbers on input, and numbers to text on output, especially floating point. 这将告诉我是否可以用二进制而不是文本来进行I / O,因为实际上,到目前为止,大部分处理将是在输入时将文本转换为数字,而在输出时将数字转换为文本,特别是浮点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM