發表文章

目前顯示的是有「檔案處理」標籤的文章

財政部電子發票平台 Turnkey 接收檔案檢測程式(小工具)

圖片
Turnkey 是財政部電子發票平台的一套傳送工具 說真的,這套工具還蠻陽春的,對於有獨立伺服器的公司來說,不是很好用。 首先,它必須在使用者登入的桌面中執行,無法作為服務使用 其次,它執行排程時,背後一堆開啟的視窗不能關掉 最後,處理狀況的查詢,只能在該機器上直接查詢,無法透過遠端查詢(這個真的麻煩,尤其伺服器不能隨便把帳號密碼給使用者) 這次會開發這個工具的原因在於, 財務單位她們有自己的系統會產生傳給Turnkey的XML檔案,並直接丟到Turnkey處理的資料夾下 有時後,財務的系統沒有正常產生,導致電子發票平台一直沒收到資料,搞到去懷疑Turnkey主機有問題。 因此,特別開發這樣的程式來檢測Turnkey處理資料夾下是否有檔案被丟進來,並且整理後發郵件告知使用者。 先看看Turnkey處理資料檔案的類型與結構 相對於Turnkey處理黨案的預設路徑在 C:\Program Files\EINVTurnkey\UpCast 該路徑下的資料夾結構會有對應的名稱 下面還有分類資料夾: 每個分類資料夾下還會有3個資料夾,分別是SRC、BAK、ERR 通常新進來的檔案都會放在SRC裏面,經由Turnkeyt處理以後會從SRC移除並分類放在BAK和ERR裏面 所以這支程式就是專門在偵測SRC的檔案出現,並收集檔案名稱並以郵件回報給相關使用者 程式名稱:TKReceiveDetect.exe ( 下載 ) 環境需求:dotNetFrameWork 4.5 它的偵測方式不是用定時檢查,而是使用Windows的是件觸發,因為定時檢查的間隔可能會造成檢查遺失,就是當檔案進入SRC資料夾後,直到Turnkey排程觸發取走檔案時,如果定時檢查錯過這段時間這時就會檢查不到,而若把定時檢查設定太短,則會削弱大量系統效能(檢查這些資料夾必須使用遞迴處理),而且檢查時,若檔案此時被Turnkey處理掉,也是會造成偵測漏洞。 使用事件觸發通知好處是非常即時,而且事件被觸發時就會告知目前檔案狀況。因此不會漏掉要接收的資訊。

C# 自訂 XCOPY 類別 :複製資料夾內所有檔案與子資料夾內容到目的資料夾(並覆蓋)

圖片
Xopy.class using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace Tools {     public class Xcopy     {         private string _message;         /// <summary>         /// 錯誤訊息         /// </summary>         public string Message         {             get { return _message; }         }         /// <summary>         /// 複製檔案群         /// </summary>         /// <param name="_source">來源資料夾</param>         /// <param name="_target">目的資料夾</param>         /// <param name="recursive">包含子資料夾</param>         /// <returns>成功 = 1 , 失敗 = -1</returns>         public int Copy(string _source, string _target, bool recursive = true)         {             try             {                 if (!Directory.Exists(_source))                 {                     _message = "來源資料夾不存在!";                     return

LaunchMan : start and check version and update 自訂啟動更新程式

圖片
  說明: 這支程式的用途就是和你的程式擺在一起,然後將這支程式設定成你的程式啟動用。 這支程式啟動時,會依照 INI檔的設定去幫你檢查程式版本。 如果有版本異動時,會提醒使用者要更新程式。 支援: 支援HTTP和FTP協定,可以依照你的需求把更新檔案放在WEB server或是FTP server上 環境: 僅能運行在Windows 下 由 dotNet 4.5 開發,需要作業系統支援 dotNet 4.5 的程式執行, 如果沒有,可以 下載安裝 dotNet FrameWork 4.5 套件 。 下載: LaunchMan 範例: 我有一個 kiosk 程式 main.exe 放在  C:\APP\KioskPatch 桌面上有個程式捷徑連結到 C:\APP\KioskPatch\main.exe 現在,我們把 LaunchMan 程式和這個 Kiosk 程式放在一起 (不放一起其實也可以,這樣比較好管) 修改桌面捷徑改連結到 C:\APP\KioskPatch\LaunchMan.exe 而更新檔案 有兩個 一個是 version.txt , 另一個為壓縮檔( 例如KioskPatch.ZIP ) 都放在我的網站 www.mycomp.com.tw/Patch/down/ 下 然後在 C:\APP\KioskPatch 下也放一個 version.txt 這兩個 version.txt 內容要不一樣,當內容不同時,才會啟動更新 然後,修改 INI 檔案(範例在下方) [Application] ;使用的背景圖片,自訂圖片,該圖片必須有DPI資訊才能正常顯示 LogoPicture=splash2.png ;淡入效果時間 ;Second unit FadeINDuration=3 FadeOutDuration=1 ;讓背景透明 BackgroundTransparency=true ;顯示訊息文字顏色/位置 MessageTextColor=#0000FF MessageLeftPosition=10 messageTopPosition=130 Title="Kiosk Sell System with .Net" TitleTextColor=#FF0000 TitleLeftPosition=50

C# csv 檔匯入 List 一行搞定

圖片
  我有一個CSV 檔案(data.csv),內容大約如下: 編號,姓名,性別 T001,林黃頻,男 T002,江國勘,男 T003,劉簿相,男 所以,依照欄位我會定義出一個儲存用類別(Field.cs): namespace MyApp {     class Field     {         public Field(string Line)         {             var sp = Line.Split(',');             UserNo = sp[0];             UserName = sp[1];             Gender = sp[2];         }         public string UserNo { get; set; }         public string UserName { get; set; }         public string Gender { get; set; }                 public override string ToString()         {             string output =  UserNo+ "\t" + UserName + "\t" + Gender + "\r\n";             return output;         }     } } 主要程式碼其實只要一行就可以搞定(不含using) using System.IO ‧ ‧ ‧ // 這一行讀入CSV併排除第一行標題 List<Field> content = File.ReadAllLines("D:\\data.csv", Encoding.Default).Select(line => new Data1(line)).Skip(1).ToList(); // 顯示出來 foreach(Data1 item in totl) {      textBox1.Text += item.ToString(); } ‧ ‧ ‧

java.lang.NoSuchMethodError : org.apache.poi.poifs.filesystem.POIFSFileSystem.hasPOIFSHeader(Ljava/io/InputStream;)Z 問題解決方法

圖片
這個是在使用 POI 讀取 EXCEL 的 xlsx 檔案造成的 LOCAL.WorkBook = WorkBookFactory.create(FileStream); 使用 WorkBookFactory.create 時內部會呼叫 POIFSFileSystem.hasPOIFSHeader 函式。  如果呼叫失敗就出現這個錯誤訊息。 所以正常來說 POIFSFileSystem.class 裡面是包含 hasPOIFSHeader 函式的。 看大部分網路上的論壇討論結果或是意見,通常是 POI 所需使用的 jar 檔案使用了不匹配/不同版本的套件導致。 但這個問發現在我另一個 jetty 版的 Railo 4.0.4.001 伺服器上卻不會發生。 為什麼?兩個伺服器版本都是一樣的啊?裡面套件也應該相同的啊? 為此,我便進行研究了一下。 1、 發生這個錯誤 的伺服器是以 Tomcat7 執行的伺服器,而另一個 不會發生 這個錯誤的是以 jetty 執行的伺服器。而兩方的版本都是當初官方公佈的 4.0.4.001 版本。 2、比對兩邊使用 POI 的 jar 檔案,雙方的檔案尺寸是相同的,檔案數量也相同。     在此處 POI 相關的 jar 共有4個,這些都是同時隨伺服器版本一起發佈的,不是我另外安裝的,應該不會存在版本問題吧。 3、如果 POIFSFileSystem.class 不包含 hasPOIFSHeader 函式,理論上 jetty 伺服器也會出現錯誤。結果卻沒有發生這個錯誤,代表 POIFSFileSystem.class 是正確的。 但,為甚麼? 所以我用解壓縮軟體來觀察 jar 檔案的成員。 發現了奇怪的的是在 apache-poi.jar 和 apache-poi-tm-extractors.jar 裡面都出現了成員 POIFSFileSystem.class ,而且檔案尺寸完全不一樣! 而且路徑都在 org.apache.poi.poifs.filesystem 下,我猜這就是貓膩了。 因為在這種情況下只會有一個成員會被載入成功,至於是哪一個先被載入要看伺服器核心的 javaloader 處理規則。 因此,我把這兩個 jar 檔案分別解

Coldfusion 隱蔽式下載

圖片
一般下載時,通常會使用 <a href="URL" /> 這種方式使用者下載,而 URL 大多的做法是指明檔案所在的位置例如  <a href="http://MySite.com/download/picture/myPicture.png">。 這種方式有幾個問題: 1、如果使用者取得此聯結位址後,可以單獨由此取得檔案或盜連,故被直接拿到的風險會很高,因為這個 URL 就是一個開放的位址。 2、由於直接指定檔案位置,很多時候檔案就會被瀏覽器直接開啟,而非下載存檔,對於大部分使用者來說,這是一個貼心的模式,但是對於很多需要下載的商業用途場合就很麻煩,使用者還必須在聯結上按『右鍵』選擇『另存檔案』的方式,操作相當不便。 3、無法設定檢查使用者取得檔案的條件。 因此,透過隱蔽式下載就是一種很好的方法。 程式碼: < cfsetting enablecfoutputonly = "yes" > <!--- 避免下載檔案遇到中文檔名無法正常下載問題而使用的功能,也可以避免使用者知道實際檔案儲存位置 ---> <!--- Arguments : file = 指定檔案名稱 ---> < cftry > <!--- 判斷使用者來源聯結是否來自本伺服器 或是直接下載,當直接下載時 REFERER 會是 空值--->     < cfif findnocase (CGI.SERVER_NAME,CGI.HTTP_REFERER) LTE 0 >     < cfthrow type = "RefererError" message = "#CGI.HTTP_REFERER#:不允許存取" >     </ cfif > <!--- 判斷參數是否存在 ---> < cfif not isdefined ( "file" )>     < cfthrow type = "Arguments" message = "

檔案編碼轉換小工具

圖片
檔案: FileEncode.exe 運行環境: .NET 2.0 Runtime 注意,這是編碼轉換,不是翻譯喔!! 某些時候在一些新舊系統文件上就是會遇到編碼文件需求不同而傷腦筋,在某些舊程式上就是如此,也無法再改動或是更新等問題,文件本身的編碼就會導致文件交易相當不順暢。 這支小程式就是用來解決這些問題的。 但要注意的是,UNICODE萬國編碼的文字一定會比舊式編碼大得多,可能會遇到某些文字無法轉換問題,例如簡體中文(GB)轉繁體中文(BIG5)。 對於英數字文件轉換是有一定實用性的。 通常新系統會使用UTF-8編碼,舊系統會使用 BIG5編碼/ANSI編碼/ISO8895-1編碼之類的。 我這邊最多用到的是 BIG5 (950) 轉 UTF-8 (65001) 需要用的自己下載去玩吧。 下載點 使用方式: 編碼類型: 37 - IBM037 437 - IBM437 500 - IBM500 708 - ASMO-708 720 - DOS-720 737 - ibm737 775 - ibm775 850 - ibm850 852 - ibm852 855 - IBM855 857 - ibm857 858 - IBM00858 860 - IBM860 861 - ibm861 862 - DOS-862 863 - IBM863 864 - IBM864 865 - IBM865 866 - cp866 869 - ibm869 870 - IBM870 874 - windows-874 875 - cp875 932 - shift_jis 936 - gb2312 949 - ks_c_5601-1987 950 - big5 1026 - IBM1026 1047 - IBM01047 1140 - IBM01140 1141 - IBM01141 1142 - IBM01142 1143 - IBM01143 1144 - IBM01144 1145 - IBM01145 1146 - IBM01146 1147 - IBM01147 1148 - IBM01148 1149 - IBM01149 120

小工具開發 - 檔案實序排定器

圖片
最近遇到某些音樂播放器,由其是SONY的車用音響,都出現了這個問題,就是它根本不照我們放置檔案的順序或是其他排序方式(時間)去撥放。而這支程式就是用來重建他的檔案順序用的。 At some Sony music players or car audios,  it read mp3 files order is not follow filename sort or otherwise sort on the USB drive. This program will regenerate file order to the right! 假如我有一個USB隨身碟資料夾,裡面的檔案清單就如下面這張圖: 在 Windows 檔案總管下,看起來就是上面這樣子的,因為檔案總管會預設以檔案名稱來排序,正常得情況我們在 Windows 的播放軟體也會依照這個規則來執行。 然而,目前我在SONY音樂播放器上遇到這個播放順序的問題,它是照下面這種順序去撥放的: 比較前後兩張清單後注意到了嗎? 第二章的清單順序根本不知道它是依循啥麼的啊??事實上這就是我在 SONY音樂播放器上遇到的問題。 經過不斷的檢查後發現,原來第二張的檔案順序是在 FAT 表上的出現順序啊!!!!! 這啥鬼? 原來 SONY 音樂播放器是直接照 FAT 表讀出的檔案順序來播放音樂的,無怪乎我怎麼改檔案名稱,或是檔案時間都沒有用。 要是按照這種方式播放的話,如果要整理檔案,就得把 MP3 檔全部 移出 USB 隨身碟後,再依順序一個一個拷貝(搬移)回 USB 隨身碟。 真是天殺的,如果 USB 隨身碟有滿滿 16 GB音樂檔,那不就搬到天花地老了。這個會死人啊,老兄。SONY,我真服了你們了,東西又不便宜,程式卻寫得這麼爛,真不像 SONY 的產品啊。 索性,自己寫一支程式,專門來做檔案順序『重建』就可以保證在 FAT 上是依照自己訂的順序來跑了。 有興趣的就自己下載看看: 下載檔案/原始碼 這是用 dotNetFramwork 4.5 製作的,所以要執行的話,電腦至少要能支援 dotNetFramwork 4.5 ,或是到 這裡下載 。記得選擇您使用的語系再安裝。 程式載點 (Google drive) 原始碼載點 (Gith

C# 偵測資料夾內檔案狀態是否被鎖定(或是可用)

參考來源: https://stackoverflow.com/questions/876473/is-there-a-way-to-check-if-a-file-is-in-use 因為常常會用到,所以先收集起來,註解改用中文 記得要 using System.IO; DirectoryInfo directoryInfo = new DirectoryInfo (sourcePath); foreach(FileInfo fi in directoryInfo.GetFiles()) {     if (!isFileLocked(fi) && fi.Length > 0)     {         // ...繼續處理可用檔案     } } 這個 isFileLocked 如下: protected virtual bool IsFileLocked(FileInfo file) {     FileStream stream = null;     try     {         stream = file.Open( FileMode .Open, FileAccess .Read, FileShare .None);     }     catch ( IOException )     {         //檔案無法開啟可能原因:         // 檔案仍然被寫入狀態         // 被其他Thread程序使用中         // 已經不存在 (或被程序處理掉了)         return true ;     }     finally     {         //如果已經被開啟不管狀態為何,記得要關閉資源         if (stream != null)             stream.Close();     }     //可以被開啟,回報檔案未被鎖定     return false ; }