2012-09-11 34 views
0

考慮下面的示例代碼:它寫入一個文件的MongoDB,然後嘗試重新讀取它讀取文件內容與卡斯巴GridFS的拋出MalformedInputException

import com.mongodb.casbah.Imports._ 
import com.mongodb.casbah.gridfs.Imports._ 

object TestGridFS{ 
    def main(args: Array[String]){ 
     val mongoConn = MongoConnection() 
     val mongoDB = mongoConn("gridfs_test") 
     val gridfs = GridFS(mongoDB) // creates a GridFS handle on ``fs`` 
     val xls = new java.io.FileInputStream("ok.xls") 
     val savedFile=gridfs.createFile(xls) 
     savedFile.filename="ok.xls" 
     savedFile.save 
     println("savedfile id: %s".format(savedFile._id.get)) 
     val file=gridfs.findOne(savedFile._id.get) 
     val bytes=file.get.source.map(_.toByte).toArray 
     println(bytes) 
    } 
} 

這會產生

gridfs $ sbt run 
[info] Loading global plugins from /Users/jean/.sbt/plugins 
[info] Set current project to gridfs-test (in build file:/Users/jean/dev/sdev/src/perso/gridfs/) 
[info] Running TestGridFS 
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". 
SLF4J: Defaulting to no-operation (NOP) logger implementation 
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. 
savedfile id: 504c8cce0364a7cd145d5dc1 
[error] (run-main) java.nio.charset.MalformedInputException: Input length = 1 
java.nio.charset.MalformedInputException: Input length = 1 
    at java.nio.charset.CoderResult.throwException(CoderResult.java:260) 
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:319) 
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158) 
    at java.io.InputStreamReader.read(InputStreamReader.java:167) 
    at java.io.BufferedReader.fill(BufferedReader.java:136) 
    at java.io.BufferedReader.read(BufferedReader.java:157) 
    at scala.io.BufferedSource$$anonfun$iter$1$$anonfun$apply$mcI$sp$1.apply$mcI$sp(BufferedSource.scala:38) 
    at scala.io.Codec.wrap(Codec.scala:64) 
    at scala.io.BufferedSource$$anonfun$iter$1.apply(BufferedSource.scala:38) 
    at scala.io.BufferedSource$$anonfun$iter$1.apply(BufferedSource.scala:38) 
    at scala.collection.Iterator$$anon$14.next(Iterator.scala:148) 
    at scala.collection.Iterator$$anon$25.hasNext(Iterator.scala:463) 
    at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334) 
    at scala.io.Source.hasNext(Source.scala:238) 
    at scala.collection.Iterator$$anon$19.hasNext(Iterator.scala:334) 
    at scala.collection.Iterator$class.foreach(Iterator.scala:660) 
    at scala.collection.Iterator$$anon$19.foreach(Iterator.scala:333) 
    at scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:48) 
    at scala.collection.mutable.ArrayBuffer.$plus$plus$eq(ArrayBuffer.scala:99) 
    at scala.collection.TraversableOnce$class.toBuffer(TraversableOnce.scala:250) 
    at scala.collection.Iterator$$anon$19.toBuffer(Iterator.scala:333) 
    at scala.collection.TraversableOnce$class.toArray(TraversableOnce.scala:237) 
    at scala.collection.Iterator$$anon$19.toArray(Iterator.scala:333) 
    at TestGridFS$.main(test.scala:15) 
    at TestGridFS.main(test.scala) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
java.lang.RuntimeException: Nonzero exit code: 1 
    at scala.sys.package$.error(package.scala:27) 
[error] {file:/Users/jean/dev/sdev/src/perso/gridfs/}default-b6ab90/compile:run: Nonzero exit code: 1 
[error] Total time: 1 s, completed 9 sept. 2012 14:34:22 

我不明白charset問題可以是什麼,我只是將文件寫入數據庫。當查詢基地時,我會看到裏面的文件和塊,但似乎無法讀取它們。

我試着用mongo 2.0和2.2,casbah 2.4和3.0.0-M2無濟於事,也沒有看到我能做些什麼來獲得Mac OSX山獅子上的字節。

PS:要運行測試,你可以使用下面的build.sbt

name := "gridfs-test" 

version := "1.0" 

scalaVersion := "2.9.1" 

libraryDependencies += "org.mongodb" %% "casbah" % "2.4.1" 

libraryDependencies += "org.mongodb" %% "casbah-gridfs" % "2.4.1" 

resolvers ++= Seq("Typesafe Releases" at "http://repo.typesafe.com/typesafe/releases/", 
     "sonatype release" at "https://oss.sonatype.org/content/repositories/releases", 
     "OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/") 

這裏是堆棧跟蹤我得到:

回答

0

我找到了一種方法來讀取文件內容重新從MongoDB的。源方法依賴於在GridFSDBFile中定義的underlying.inpustream。

我做的每個使用了underlying.inpustream的測試都失敗了,並且出現了同樣的錯誤。 但是,API提出了另一種訪問文件的方式:writeTo。 writeTo不使用underlying.inpustream。

下面是從問題的「固定」的代碼:

import com.mongodb.casbah.Imports._ 
import com.mongodb.casbah.gridfs.Imports._ 

object TestGridFS{ 
    def main(args: Array[String]){ 
     val mongoConn = MongoConnection() 
     val mongoDB = mongoConn("gridfs_test") 
     val gridfs = GridFS(mongoDB) // creates a GridFS handle on ``fs`` 
     val xls = new java.io.File("ok.xls") 
     val savedFile=gridfs.createFile(xls) 
     savedFile.filename="ok.xls"  
     savedFile.save 
     println("savedfile id: %s".format(savedFile._id.get)) 
     val file=gridfs.findOne(savedFile._id.get) 
     val byteArrayOutputStream = new java.io.ByteArrayOutputStream() 
     file.map(_.writeTo(byteArrayOutputStream)) 
     byteArrayOutputStream.toByteArray 
    } 
} 

最後一行,byteArrayOutputStream.toByteArray給你然後可以使用但你認爲合適的字節數組。