2014-09-29 54 views
4

這是一個問題,在接受採訪時詢問我,但仍找不到方法 -刪除文件的最後4個字節而不打開文件?

假設我有一個.txt文件,我想從該內容中刪除最後4個字符文件而不打開文件。第一個問題是 - 它真的可行嗎?如果是,那麼做法是什麼?

+4

那麼你至少應該嚴格定義什麼是「打開文件」的意思。 – 2014-09-29 11:43:22

+2

「最後4個字節」(標題)和「最後4個字符」(正文)之間有一個**非常重要的區別**。請澄清。另外:爲什麼你不想打開文件?注意:打開文件並不意味着*讀取所有文件。 – 2014-09-29 11:56:00

+1

我猜OP不知道「打開文件」是什麼意思。他們希望他考慮一下,然後問清楚這個問題...... – Alexander 2014-09-29 12:10:32

回答

3

我猜你無法讀取的值對應於文件

  • 更新的條目(寫)項文件的內容。所以,如果你可以寫「開放」它只能訪問你可以這樣做:

    using (var fileStream = File.Open("initDoc.txt", FileMode.Open, FileAccess.Write)) 
    { 
        fileStream.SetLength(fileStream.Length - 4); 
    } 
    

    當然,你將需要額外的檢查,以確保您減去根據編碼正確的字節數,不扣除超過長度等。

    如果您不能使用FileMode.Open,則可以使用使用SafeFileHandle的FileStream構造函數的重載。要獲取文件的SafeFileHandle,您需要使用C#Interop。在這個例子中下面我纏互操作的代碼來獲得一個文件句柄在一個名爲「UnmanagedFileLoader」類:

    var unmanagedFileLoader = new UnmanagedFileLoader("initDoc.txt"); 
    
    using (var fileStream = new FileStream(unmanagedFileLoader.Handle, FileAccess.Write)) 
    { 
        fileStream.SetLength(fileStream.Length - 4); 
    } 
    

    的UnmanagedFileLoader內部使用的非託管CreateFile函數打開現有的文件具有寫權限:

    handleValue = CreateFile(Path, GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); 
    

    欲瞭解更多信息如何獲取SafeFileHandle你可以看看這個鏈接:

    http://msdn.microsoft.com/en-us/library/microsoft.win32.safehandles.safefilehandle%28v=vs.110%29.aspx

    如果你想跳過FileStream方式,第三種方法是使用StreamReader和StreamWriter,然後用StreamReader讀取一個沒有最後4個字節的文件,然後用StreamWriter寫入。但我仍然推薦使用上面的FileStream示例。

  • +0

    沒有人知道OP意味着什麼「打開文件」,但調用'File.Open'似乎並沒有回答IMHO的問題... – ken2k 2014-09-29 12:05:23

    +0

    我同意Marc Gravell對此。可能禁止閱讀完整的內容。但讓我們等待確認。 – 2014-09-29 12:08:59

    +0

    我被問到沒有使用FileMode.Open .....(在微軟訪談中問我) – 2014-10-01 05:13:13

    2

    編輯:我假設「打開文件」的意思是「獲取文件的句柄」。

    當然這是可能的:

    • 打開的句柄包含該文件的驅動器
    • 獲取文件系統類型
    • 掃描包含有關的所有文件的信息結構的內容:在MFT (對於NTFS),FAT記錄..等等。
    • 查找減去4到存儲「文件大小」的信息:)
    +2

    損壞的文件系統在這裏我們來...但是是... :) – DarkSquirrel42 2014-09-29 11:59:52

    +0

    這樣做的腐敗風險是什麼? – BlueTrin 2014-09-29 12:04:40

    +2

    @BlueTrin它完全繞過操作系統和文件子系統,並且意味着實現需要知道文件系統的確切細節。一個錯誤(無論是一個錯誤,還是因爲它使用了一個意想不到的文件系統的子版本),並且該驅動器的這個區域最終會變得不可讀,直到被刪除。 – 2014-09-29 12:10:49

    0

    如果您關心的是讀取長文件的所有數據:這不是必需的。如果我們假設你真的意味着字節的,簡單地說:

    using (var file = File.Open(path, FileMode.Open, FileAccess.Write)) { 
        file.SetLength(file.Length - 4); 
    } 
    

    這樣做閱讀內容的文件的

    如果你的意思是字符,那麼你需要仔細考慮編碼--4個字符不一定是4個字節。

    +0

    沒有人知道OP通過「打開文件」的意思,但調用「File.Open」似乎並沒有回答這個問題恕我直言...... – ken2k 2014-09-29 12:05:53

    +0

    @ ken2k我強烈懷疑OP的意思是「沒有閱讀(所有)文件「 - 在這種情況下,這應該工作 – 2014-09-29 12:07:01

    +0

    謝謝你們。我已經嘗試了您提供的解決方案,並且它可以工作。不知道面試官是否在尋找相同的方法。讓我們把它留給這個。 – 2014-10-01 05:16:40

    相關問題