none
string的容量的问题 RRS feed

  • 问题

  • 我现在在做一个读取pdf文件页数的问题。采用的是把pdf文件用流打开,然后匹配里面的字符窜“Type Page”,这个是pdf文件专用的分页符。

    于是我写了如下的代码。现在我遇到了一个比较多页数的pdf文件(大概有1300页),在我测试时发现系统会崩溃,进过端点测试发现是在定义string的类型读取流文件时崩溃的。我的猜测是可能是string容量被撑破了。想问下各位版主,遇到这种问题,有什么解决方法,如果没有解决方案,可以提供一个跳过的不让系统崩溃的方法么。

            Dim fs As FileStream = New FileStream(PathName, FileMode.Open, FileAccess.Read)
            Dim r As StreamReader = New StreamReader(fs)
    
            Dim pdfText As String = r.ReadToEnd
    
            Dim rx1 As Regex = New Regex("/Type\s*/Page[^s]")
            Dim mathces As MatchCollection = rx1.Matches(pdfText)
    

     

    2010年7月20日 9:42

答案

  • 你好

    請問你知不知道 那裡開始系统崩溃?

    是 r.ReadToEnd時 還是 用REGEX 時?不知道會不會因為電腦不夠RAM...

    可不可以試試用STRINGBUILDER 看看 效果會不會好一點

    例如:

    Dim sb as New StringBuider

    sb.Append(r.ReadToEnd)

     Dim
     mathces As
     MatchCollection = rx1.Matches(pdfText)
    轉成
    Dim mathces As MatchCollection = rx1.Matches(sb.ToString())


    Please correct me if my concept is wrong

    Chi
    • 已标记为答案 Fenix.1986 2010年7月26日 1:28
    2010年7月20日 12:39
    版主

全部回复

  • 你好

    請問你知不知道 那裡開始系统崩溃?

    是 r.ReadToEnd時 還是 用REGEX 時?不知道會不會因為電腦不夠RAM...

    可不可以試試用STRINGBUILDER 看看 效果會不會好一點

    例如:

    Dim sb as New StringBuider

    sb.Append(r.ReadToEnd)

     Dim
     mathces As
     MatchCollection = rx1.Matches(pdfText)
    轉成
    Dim mathces As MatchCollection = rx1.Matches(sb.ToString())


    Please correct me if my concept is wrong

    Chi
    • 已标记为答案 Fenix.1986 2010年7月26日 1:28
    2010年7月20日 12:39
    版主
  • 很感谢ChiYau的细心解答。我按照你的方法试过了。不过还是不行。还是在r.ReadToEnd这句话里面崩溃了。这么看来,应该是内容的问题,而不是stringD的问题了

    2010年7月21日 2:25
  • 你好

    可不可嘗試用TRY AND CATCH 去看看

    出問題的錯誤是什麼

    待我們可以更加了解這個問題


    Chi
    2010年7月21日 3:58
    版主
  •  chi ,你好。我后来改进了代码,不用ReadToEnd方法,而是用Read每次读64k,我以为这样应该可行了,但可惜的是问题依旧存在,并且Try Catch也无法报错。直接崩溃了。下面是代码。

        Public Shared Function GetPdfCounts(ByVal PathName As String)
          Dim ex As Exception
    
          Try
    
            Dim builder As New StringBuilder
            Dim fs As FileStream = File.OpenRead(PathName)
    
            Dim n As Integer = 64 * 1024 '当次读取长度
            Dim pack_length As Integer = 64 * 1024 '阀值
    
            Dim buf(pack_length) As Byte
            Do Until n < pack_length
              n = fs.Read(buf, 0, pack_length)
              If n < pack_length Then ReDim Preserve buf(n)
              builder.Append(Encoding.Default.GetString(buf))
            Loop
    
            Dim s As String = builder.ToString()
    
            Dim rx1 As Regex = New Regex("/Type\s*/Page[^s]")
            Dim mathces As MatchCollection = rx1.Matches(s)
    
            fs.Close()
            Return mathces.Count
          Catch ex
            MsgBox(ex.Message)
          End Try
    
          Return 0
        End Function
    
    2010年7月21日 7:37
  • 你好

    不知道你的PDF 有多大, 大概有多小文字

    你可不可以方個 BREAKPOINT 在

        Dim
     s As
     String
     = builder.ToString()

    看看是 ASSIGN 去STRING 時的問題

    還是 在 DO UNTIL 中已經 出現問題

    Please forgive me if my concept is wrong


    Chi
    2010年7月21日 7:58
    版主
  • Chi ,你好! 刚才设断点试了一下,确实是在循环里崩溃的了,而不是在dim s as string 这句话里崩溃的。估计是我循环的代码有错误,可以指点一下么。
    2010年7月21日 9:00
  • 你好

    可不可以幫我做一個TEST

    看看你的文件有多小個 字元

    Dim Test_fs As FileStream = New FileStream(PathName, FileMode.Open, FileAccess.Read)
    Dim Test_r As StreamReader = New StreamReader(Test_fs )


    dim txtSize as Long = Test_r.ReadToEnd.Length
    msgbox (txtSize)

    Dim builder As New StringBuilder(txtSize  + 100000)


    我想知道你的 PDF 會READ 到多小個字元出來

    不知道會不會是大過STRINGBUILDER 的 DEFAULT CAPACITY

    可不可以同時看看你電腦的RAM 的用量

    在 CRASH 前 還有多小FREE

    不好意思我也不知清楚怎樣解決這個問題

    Please correct me if my concept is wrong



    Chi
    2010年7月21日 10:26
    版主
  • chi ,你好! 我按照你的代码测试了下,在MsgBox前系统就崩溃了,而且我看了内存,并没有Crash掉,只用了三分之一而已。
    2010年7月22日 6:47
  • 你好

    不知道是不是

    LONG 不夠大

    或者你可以試試轉LONG 成 DECIMAL 看看

    我想知道是在 Test_r.ReadToEnd 有問題, 因為 FILE 太大 還是因為個 .LENGTH 大過 LONG 可以存的值

    dim txtSize as Decimal= Test_r.ReadToEnd.Length

    再試試吧

    我也不太清楚問題出在那裡

    不知道可不可以UPLOAD 這個PDF 給我們嘗試

    please forgive me if my concept is wrong


    Chi
    2010年7月22日 7:23
    版主
  • 你好!

        请问抛出的具体是哪个异常?


    周雪峰
    2010年7月22日 13:48
    版主
  • Chi ,你好。

        我并不懂得怎么upload,其实只要大点的pdf应该都可以替代。差不多1000张左右的pdf就可以了。我的思路是用流来打开它,然后在里面用正则表达式去匹配。所以很可能是文件过大使得readtoend函数占用了过多内存(超出clr可以允许的了)。我尝试用记事本来打开这个pdf,发现很久时间也打不开。既然记事本都打不开的话,应该是string也容纳不下吧。

        不知道我的这些猜测正不正确。

    2010年7月23日 2:03
  • 周版主,你好!

         我的程序并没有抛出异常(虽然我设置了try,catch字段)而是直接崩溃了。其实我是在做CAD的二次开发,用的是.net的开发方式,程序崩溃时,CAD提示遇到问题,然后就自动关闭了。

    2010年7月23日 2:05
  • 你好

    "可能是文件过大使得readtoend函数占用了过多内存", 我都覺得有可能

    你這個PDF 全是文字嗎?

    有多小MB?

    或者可以試試用以下這個 TEXT EDITOR 來開

    http://www.pspad.com/

    看看能不能1

    可能會慢一點

    Please correct me if my concept is wrong


    Chi
    2010年7月23日 6:00
    版主
  • 谢谢你,chi。

                我决定对这个问题放弃了。因为确实很少有那么大的pdf文件。我的用户基本上最多也就300多张图纸。因此我决定提示他们不要放过多的图纸。这也算是个解决办法吧。总之非常感谢chi你的耐心认真。真的。很感谢。在这个过程中我也学到了很多。希望以后我有机会能解决它,但时间已经需要我继续下一个任务了。呵呵。

    2010年7月26日 1:28
  • 謝謝你 Fenix 

    不好意思, 不能解決這個問題,
    我很高興可以在這個論壇和大家交流
    我也學到了很多 =)
    如果將來你有更多的問題
    歡迎在這個論壇發表, 大家一起研究 =)

    Have a good day =)

    Chi
    2010年7月26日 5:55
    版主