2012-02-19 40 views
0

我一直在遍地搜索流文件到MySQL使用C,我找不到任何東西。這在C++,C#和許多其他語言中很容易做到,但我找不到任何直接的C語言。流文件到mysql在c

基本上,我有一個文件,並且我想將該文件讀入TEXT或BLOB列在我的MySQL數據庫。通過遍歷文件並使用隨後的調用將數據追加到列中,可以非常容易地實現此目的。但是,我認爲這不像解決方案那樣優雅,並且可能非常容易出錯。

我已經使用mysql_stmt_init()和所有綁定等來查看準備好的語句,但它似乎不接受指向數據庫的數據讀取指針FILE

重要的是要注意我正在處理非常大的文件,這些文件無法存儲在RAM中,因此將整個文件讀入臨時變量是不成問題的。

簡單地說:我怎樣才能從磁盤讀取文件到MySQL數據庫使用C?請記住,需要有某種類型的緩衝區(即由於文件大小而導致的BUFSIZ)。有沒有人做到這一點?可能嗎?而且我正在尋找一種可以同時處理文本和二進制文件的解決方案。

回答

0

我不喜歡回答我自己的問題,但我覺得需要別人在尋找解決方案。

除非我失去了一些東西,我的研究和測試表明我,我有三個常規選項:

  1. 體面的解決辦法:使用LOAD DATA INFILE語句發送文件
    • 利弊:只需要一個陳述。與將整個文件加載到內存中不同,您可以在客戶端和服務器上調整LOAD DATA的性能,以使用給定的緩衝區大小,並且可以使該緩衝區更小,這將爲您提供「更好」的緩衝區控制,調用
    • 缺點:首先,文件絕對是必須是在給定的格式,這可能很難做到二進制BLOB文件。而且,這需要大量的工作來設置,並且需要大量的調整。默認情況下,客戶端將嘗試將整個文件加載到內存中,並使用swap-space來填充不適合內存的文件量。在這裏獲得糟糕的性能是非常容易的,每次你想改變時你都必須重新啓動mysql服務器。
  2. 體面的解決辦法:有緩衝器(例如,char buf[BUFSIZ]),並進行大量的查詢與CONCAT()調用更新內容
    • 優點:使用的內存量最少,並給出了程序更好地控制正在使用多少內存
    • 缺點:佔用很多處理時間,因爲您正在進行大量的mysql調用,並且服務器必須找到給定的行,然後向其添加一個字符串(它需要蒂姆即,即使高速緩存)
  3. 最壞的解決方案:嘗試將整個文件加載到內存中(或儘可能),並只有一個INSERTUPDATE調用到mysql
    • 優點:限制了客戶端所需的處理性能數量,因爲只有最少數量的調用(最好是一個)需要被緩衝和執行。
    • 缺點:佔用TON的內存。如果您有衆多客戶同時撥打這些大型電話,服務器將會迅速耗盡內存,任何性能提升都將很快失去效能。

在一個完美的世界中,MySQL將實現一個功能,它允許緩衝查詢,一個類似於緩衝視頻:打開一個MySQL連接,然後打開一個「查詢連接」內流的然後關閉「查詢連接」

但是,這不是一個完美的世界,在MySQL中沒有這樣的事情。這給我們留下了上面顯示的三個選項。我決定堅持第二個,在那裏我撥打衆多的CONCAT()電話,因爲我目前的服務器有足夠的處理時間,我的客戶端內存非常有限。對於我獨特的情況,試圖在調整LOAD DATA INFILE時想打我的腦袋是沒有意義的。但是,每個應用程序都必須分析它自己的問題。

我會強調這些對我來說都不是「完美」的,但你只能用你所擁有的做到最好。

指向Adam Liss給出LOAD DATA INFILE方向。

0

您可以使用一個循環遍歷文件的讀取,但不是使用像fgets(),在每次讀取一行的函數,使用像read()fread()低級別的功能,將在填補一個任意大小的緩衝區時間:

allocate large buffer 
open file 
while NOT end of file 
    fill buffer 
    CONCAT to MySQL 
close file 
release buffer 
+0

我知道 - 我目前使用fread()來讀取數據。但是這並不能回答我的問題;我問這可能是怎麼做的*沒有*使用'CONCAT' – cegfault 2012-02-19 04:02:55

2

你能到mysql_query()通話使用LOAD DATA INFILE

char statement[STMT_SIZE]; 
snprintf(statement, STMT_SIZE, "LOAD DATA INFILE '%s' INTO TABLE '%s'", 
    filename, tablename); 
mysql_query(conn, statement); 

http://dev.mysql.com/doc/refman/5.6/en/load-data.htmlhttp://dev.mysql.com/doc/refman/5.6/en/mysql-query.html在MySQL的文檔相應的頁面。

+0

有趣的;我不認爲使用加載數據infile。有些文件是臨時文件,但我會看看我是否可以找到他們的名字,我會試一試。 – cegfault 2012-02-19 05:12:03

+0

祝你好運!請讓我們知道它是怎麼回事。 – 2012-02-19 05:18:21

+0

我可以讓它適用於靜態文件,但用'tmpfile()'創建的任何文件都不能保證起作用,首先是因爲我無法檢索文件的名稱,其次,因爲即使我在文件創建期間收集它的名稱,有可能這個名字從創建的時間改變到我進行mysql調用的時間(可能很長時間)。 *嘆息*我想我必須繼續尋找 – cegfault 2012-02-19 08:40:29