2016-04-11 62 views
0

我正在使用streamwriter在csv文件中播放時保存我的遊戲數據。爲了做到這一點,我在啓動函數中初始化了我的Streamwriter,併爲我的數據的頭部寫了第一行。然後在更新函數中,我在該文件中寫入變化的遊戲變量。我的問題是以下幾點:如果if語句不再正確後如何正確關閉streamwriter?

這工作正常,我可以看到我的csv文件與數據時,我單擊手動停止在遊戲中。但是,當我等到myTimer(遊戲的持續時間爲< = 0)並且GUI正在重新加載時,我只是得到一個空的csv文件。 我認爲這個問題是有關的事實,我沒有正確關閉我的StreamWriter ...這裏是我的代碼:

// Use this for initialization 
public void Start() 
{ 
    //create file (txt or csv) with streamwriter which has the name of the Subject and Information which game 
    swFeedbackGame = File.CreateText (UIManagerScript.SUBJECTID+"FeedbackGameData444.csv"); 
    //write headers to file 
    swFeedbackGame.Write ("PositionRingFeeback" + "," + "PositionSphereMiddle" + "," + "distanceRingFeedbackTOSphere" + "," + "Collisions" + "," + "Timer"+System.Environment.NewLine); 
} 

public void SaveDataFeedback() 
{ 
    //start writing in file only when feedback game is starting 
    //if (StartButtonManager.startingGame) { 

    if (StartButtonManager.startingGame) 
    { 
     //get position of center of the ring 
     PositionRingFeedback = GameObject.Find ("Ring").transform.position; 

     //position of the center of the ring (y axis) 
     PositionRINGFeedback = PositionRingFeedback.y; 

     //error, meaning difference between position of the spheremiddle and center of the ring 
     distanceRingFeedbackTOSphere = PositionRINGFeedback - Sinewave.posSpheremiddle; 

     //write data to file _ columns are separated by a , 
     swFeedbackGame.Write (PositionRINGFeedback + "," + Sinewave.posSpheremiddle + "," + distanceRingFeedbackTOSphere + "," + CounterManager.counterHitSinewave + "," + UIManagerScript.myTimer + System.Environment.NewLine); 
     swFeedbackGame.Flush(); 
    } 
    else 
    { 
     swFeedbackGame.Close(); 
    } 
} 

// Update is called once per frame 
public void FixedUpdate() 
{ 
    //saves the data from the FeedbackGame every Frame 
    SaveDataFeedback(); 
} 
+0

你可以請妥善縮進代碼 –

+1

似乎每次你重裝csv文件是重新創建,如果存在,那麼文本將appeand寫入前檢查,如果不存在則創建新文件 – Mostafiz

+1

怎麼樣'使用內部初始化() {}塊,然後將流寫入器注入到'SaveDataFeedback()'而不是依賴全局實例? –

回答

1

初始化使用像這樣的內流:

using(StreamWriter sw = new StreamWriter) 
{ 
    //your code here this 
    //this doesn't need a sw.Open(), or sw.Close() 
} 

但如果你有嵌套流,請小心。

0

您應該避免以不同的方式打開/關閉文件或保持打開和關閉之間的長距離。保持兩種操作的方法相同。

WriteAllTextAppendAllText靜態方法派上用場。他們打開文件,將內容寫入它,然後用一個語句關閉文件。

除非有太多的調用將內容寫入文件,否則我寧願使用這些方法,而不是自己明確地打開和關閉它們。

// Use this for initialization 
string FileName; 
public void Start() 
{ 
    FileName = UIManagerScript.SUBJECTID + "FeedbackGameData444.csv"; 

    //create file (txt or csv) with streamwriter which has the name of the Subject and Information which game 
    //and write headers to file 
    WriteToFile(FileName, true, "PositionRingFeeback" + "," + "PositionSphereMiddle" + "," + "distanceRingFeedbackTOSphere" + "," + "Collisions" + "," + "Timer" + System.Environment.NewLine); 
} 

public void SaveDataFeedback() 
{ 
    //start writing in file only when feedback game is starting 
    //if (StartButtonManager.startingGame) { 

    if (StartButtonManager.startingGame) 
    { 
     //get position of center of the ring 
     PositionRingFeedback = GameObject.Find("Ring").transform.position; 

     //position of the center of the ring (y axis) 
     PositionRINGFeedback = PositionRingFeedback.y; 

     //error, meaning difference between position of the spheremiddle and center of the ring 
     distanceRingFeedbackTOSphere = PositionRINGFeedback - Sinewave.posSpheremiddle; 

     //write data to file _ columns are separated by a , 
     WriteToFile(FileName, false, PositionRINGFeedback + "," + Sinewave.posSpheremiddle + "," + distanceRingFeedbackTOSphere + "," + CounterManager.counterHitSinewave + "," + UIManagerScript.myTimer + System.Environment.NewLine); 
    } 
} 

// Update is called once per frame 
public void FixedUpdate() 
{ 
    //saves the data from the FeedbackGame every Frame 
    SaveDataFeedback(); 
} 

private void WriteToFile(string fileName, bool createNew, string contents) 
{ 
    if (createNew) 
     File.WriteAllText(fileName, contents); 
    else 
     File.AppendAllText(fileName, contents); 
} 
+0

謝謝你的幫助!我不能投票你的答案...... =(這是不可能的問題是當我寫:WriteToFile,它顯示爲紅色...我需要一個特殊的工具箱嗎?當我繼續它寫它是在這種情況下不存在,非常感謝! – sportente

+0

我在代碼的末尾添加了這個方法,你有沒有想過這個? –

+0

太好了!謝謝!我會試試。我可以在哪裏選擇創建一個新文件?我正在使用MAC。 – sportente

0

OOP來到resque。

當然,它有點貴,但它是一個很好的設計,你可以隨時擴展等等。關於日誌記錄的邏輯是沒有意義的,所以調用者可以自己處理你的日誌記錄器,你只需要寫任何你想要的東西(注意你傳遞你的遊戲對象數據,記錄器爲你做所有事情)。示例代碼:

class Game 
{ 
    private readonly ILogger _logger; 

    public Game(ILogger logger) 
    { 
     _logger = logger; 
    } 

    public void Start() 
    { 
     _logger.StartWriting(); 
    } 

    public void SaveDataFeedback() 
    { 
     var dataobject = new GameData(); 
     // filling data object 
     _logger.WriteData(dataobject); 
    } 
} 

internal interface ILogger 
{ 
    void StartWriting(); 
    void WriteData(GameData data); 
} 

public class GameData 
{ 
    public double PositionRingFeeback { get; set; } 
    public double PositionSphereMiddle { get; set; } 
    public double DistanceRingFeedbackToSphere { get; set; } 
    public int Collisions { get; set; } 
    public TimeSpan Timer { get; set; } 
} 

class FileLogger : ILogger, IDisposable 
{ 
    private readonly string _filename; 
    private StreamWriter _sr; 

    public FileLogger(string filename) 
    { 
     _filename = filename; 
    } 

    public void StartWriting() 
    { 
     _sr = new StreamWriter(new FileStream(_filename, FileMode.OpenOrCreate), Encoding.UTF8); 
     _sr.WriteLine("PositionRingFeeback" + "," + "PositionSphereMiddle" + "," + "distanceRingFeedbackTOSphere" + "," + "Collisions" + "," + "Timer"); 
    } 

    public void WriteData(GameData data) 
    { 
     _sr.Write("{0}{1}{2}{3}{4}", data.PositionRingFeeback, data.PositionSphereMiddle, data.DistanceRingFeedbackToSphere, data.Collisions, data.Timer); 
    } 

    public void Dispose() 
    { 
     _sr.Dispose(); 
    } 
} 

然後被叫正在部署一個記錄器本身:

using (var logger = new FileLogger("data.txt")) 
{ 
    var game = new Game(logger); 
    game.Start(); 
} 

如果你不需要incapsulation的這樣的水平,你可以只使用事件:

class Game 
{ 
    public delegate void GameStartedHandler(Game sender, EventArgs eventArgs); 
    public delegate void GameEventHandler(Game sender, GameData eventData); 

    public event GameStartedHandler GameStarted = delegate { }; 
    public event GameEventHandler GameEvent = delegate { }; 

    public void Start() 
    { 
     GameStarted(this, EventArgs.Empty); 
    } 

    public void SaveDataFeedback() 
    { 
     var dataobject = new GameData(); 
     // filling data object 
     GameEvent(this, dataobject); 
    } 
} 

但在這種情況下被調用者更復雜,因爲它應該管理所有的日誌本身:

using (var logger = new StreamWriter(new FileStream("data.txt", FileMode.OpenOrCreate), Encoding.UTF8)) 
{ 
    var game = new Game(); 
    game.GameStarted += (sender, eventArgs) => logger.WriteLine("PositionRingFeeback" + "," + "PositionSphereMiddle" + "," + "distanceRingFeedbackTOSphere" + "," + "Collisions" + "," + "Timer"); 
    game.GameEvent += (sender, data) => logger.Write("{0}{1}{2}{3}{4}", data.PositionRingFeeback, data.PositionSphereMiddle, data.DistanceRingFeedbackToSphere, data.Collisions, data.Timer); 
    game.Start(); 
}