You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++读取实时更新CSV文件异常:重复读取初始值的解决咨询

Fixing Repeated Initial Value Reads from a Continuously Updated CSV File

Let's break down why your code is stuck reading the initial value and how to fix it:

The Root Cause

Your current code reopens the CSV file every second, but two key issues are blocking you from getting the updated value:

  1. File Locking: When the CSV is being continuously updated by another process (that keeps the file open), the default std::ifstream opening mode on Windows often locks the file or reads from a cached snapshot instead of the latest content.
  2. Unhandled Stream States: If a read fails even once, the stream's error flags can persist and block future reads unless explicitly cleared.

Solution 1: Improve std::ifstream Usage

First, let's tweak your existing code to handle shared access and reset stream states properly:

#include <vector>
#include <fstream>
#include <iostream>
#include <chrono>
#include <thread> // For cross-platform sleep

struct Node { double number; };

void readData(std::vector<Node>& Values) {
    Node Data;
    // Open in binary mode to avoid text mode quirks, and enable shared access
    std::ifstream file("file.csv", std::ios::in | std::ios::binary);
    
    if (!file.is_open()) {
        std::cerr << "Failed to open file – might be locked by another process!\n";
        return;
    }

    // Reset file pointer to the start and clear any previous error flags
    file.seekg(0, std::ios::beg);
    file.clear();

    if (file >> Data.number) {
        Values.push_back(Data);
        std::cout << "Successfully read: " << Data.number << "\n";
    } else {
        std::cerr << "Failed to parse data from file!\n";
    }

    // Explicitly close the file to release resources immediately
    file.close();
}

int main() {
    std::vector<Node> Values;
    while (true) {
        readData(Values);
        // Cross-platform sleep (replaces Windows-specific _sleep)
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    return 0;
}

Key Changes Here:

  • Binary Mode: std::ios::binary helps avoid unexpected newline conversions and improves compatibility with shared file access on Windows.
  • Stream Reset: seekg(0, std::ios::beg) ensures we always read from the start of the file, and file.clear() resets any error flags that might have been set by a failed read.
  • Cross-Platform Sleep: Replaced _sleep with std::this_thread::sleep_for to make the code work on non-Windows systems.

Solution 2: Windows API for Precise File Control

If Solution 1 still doesn't work (because the writing process has strict locking), use the Windows API's CreateFile to explicitly allow shared read/write access:

#include <vector>
#include <iostream>
#include <windows.h>
#include <cstdlib> // For atof
#include <chrono>
#include <thread>

struct Node { double number; };

bool readLatestValue(double& value) {
    // Open the file with explicit shared access rights
    HANDLE hFile = CreateFileA(
        "file.csv",
        GENERIC_READ,
        FILE_SHARE_READ | FILE_SHARE_WRITE, // Allow other processes to read/write while we access
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );

    if (hFile == INVALID_HANDLE_VALUE) {
        std::cerr << "Failed to open file. Error code: " << GetLastError() << "\n";
        return false;
    }

    char buffer[256];
    DWORD bytesRead;
    bool readSuccess = ReadFile(hFile, buffer, sizeof(buffer)-1, &bytesRead, NULL);

    if (readSuccess && bytesRead > 0) {
        buffer[bytesRead] = '\0'; // Null-terminate the buffer
        value = atof(buffer);
    } else {
        std::cerr << "Failed to read file. Error code: " << GetLastError() << "\n";
        readSuccess = false;
    }

    CloseHandle(hFile);
    return readSuccess;
}

void readData(std::vector<Node>& Values) {
    Node Data;
    if (readLatestValue(Data.number)) {
        Values.push_back(Data);
        std::cout << "Read latest value: " << Data.number << "\n";
    }
}

int main() {
    std::vector<Node> Values;
    while (true) {
        readData(Values);
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    return 0;
}

Why This Works:

CreateFile lets you specify FILE_SHARE_READ | FILE_SHARE_WRITE, which tells Windows that other processes can modify the file while you're reading it. This bypasses the default locking behavior that was causing you to read cached initial values.

Final Notes

  • If the writing process is using exclusive file access, even these solutions might fail – check that the program updating the CSV isn't locking the file completely.
  • For production code, consider adding retry logic if the file is temporarily locked instead of just failing silently.

内容的提问来源于stack exchange,提问作者michaelprogramm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:18:50