【问题标题】:How to write to HDFS using Scala如何使用 Scala 写入 HDFS
【发布时间】:2015-11-29 13:29:55
【问题描述】:

我正在学习 Scala,我需要将自定义文件写入 HDFS。我在笔记本电脑上使用 vmware fusion 在 Cloudera 映像上运行了自己的 HDFS。

这是我的实际代码:

package org.glassfish.samples

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.PrintWriter;

/**
* @author ${user.name}
*/
object App {

def main(args : Array[String]) {
println( "Trying to write to HDFS..." )
val conf = new Configuration()
val fs= FileSystem.get(conf)
val output = fs.create(new Path("hdfs://quickstart.cloudera:8020/tmp/mySample.txt"))
val writer = new PrintWriter(output)
try {
    writer.write("this is a test") 
    writer.write("\n")
}
finally {
    writer.close()
}
print("Done!")
}

}

我得到了这个例外:

Caused by: java.lang.IllegalArgumentException: Wrong FS: hdfs://quickstart.cloudera:8020/tmp, expected: file:///
at org.apache.hadoop.fs.FileSystem.checkPath(FileSystem.java:645)
at org.apache.hadoop.fs.RawLocalFileSystem.pathToFile(RawLocalFileSystem.java:80)
at org.apache.hadoop.fs.RawLocalFileSystem.mkdirs(RawLocalFileSystem.java:414)
at org.apache.hadoop.fs.ChecksumFileSystem.mkdirs(ChecksumFileSystem.java:588)
at org.apache.hadoop.fs.ChecksumFileSystem.create(ChecksumFileSystem.java:439)
at org.apache.hadoop.fs.ChecksumFileSystem.create(ChecksumFileSystem.java:426)
at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:908)
at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:889)
at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:786)
at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:775)
at org.glassfish.samples.App$.main(App.scala:19)
at org.glassfish.samples.App.main(App.scala)
... 6 more

我可以使用终端和 Hue 访问 hdfs

[cloudera@quickstart ~]$ hdfs dfs -ls /tmp
Found 3 items
drwxr-xr-x   - hdfs     supergroup          0 2015-06-09 17:54 /tmp/hadoop-yarn
drwx-wx-wx   - hive     supergroup          0 2015-08-17 15:24 /tmp/hive
drwxr-xr-x   - cloudera supergroup          0 2015-08-17 16:50 /tmp/labdata

这是我的pom.xml

我使用以下命令运行项目:

mvn clean package scala:run

我做错了什么?提前谢谢你!

在@jeroenr 建议后编辑

这是实际代码:

package org.glassfish.samples

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.PrintWriter;

/**
* @author ${user.name}
*/
object App {

//def foo(x : Array[String]) = x.foldLeft("")((a,b) => a + b)

def main(args : Array[String]) {
println( "Trying to write to HDFS..." )
val conf = new Configuration()
//conf.set("fs.defaultFS", "hdfs://quickstart.cloudera:8020")
conf.set("fs.defaultFS", "hdfs://192.168.30.147:8020")
val fs= FileSystem.get(conf)
val output = fs.create(new Path("/tmp/mySample.txt"))
val writer = new PrintWriter(output)
try {
    writer.write("this is a test") 
    writer.write("\n")
}
finally {
    writer.close()
    println("Closed!")
}
println("Done!")
}

}

【问题讨论】:

    标签: scala hadoop hdfs


    【解决方案1】:

    看看这个this example here。我认为问题在于您没有使用配置默认文件系统

    conf.set("fs.defaultFS", "hdfs://quickstart.cloudera:8020")
    

    并传递相对路径,如下所示:

    fs.create(new Path("/tmp/mySample.txt"))
    

    要写入文件,直接在fs.create返回的输出流上调用'write',像这样:

    val os = fs.create(new Path("/tmp/mySample.txt"))
    os.write("This is a test".getBytes)
    

    【讨论】:

    • 嗨@jeroenr,谢谢你的建议。补丁后我可以在 hdfs 中看到新文件但没有内容,很奇怪不是吗?我可以在终端上看到消息 Closed and Done。
    • @aironman 我不了解端口,但我相信您应该直接在 'fs.create(new Path("/tmp/mySample.txt" ) 的返回值上调用 'write' ))'。所以: val output = fs.create(new Path("/tmp/mySample.txt")) output.write("this is a test").getBytes
    • midgetontoes.com/blog/2014/10/04/… 现在是死链接。
    • 就我而言,我必须调用.close() 来执行写入。 .hflush().hsync() 均未执行对远程位置的写入。
    猜你喜欢
    • 1970-01-01
    • 2019-12-21
    • 2016-09-10
    • 2021-11-20
    • 1970-01-01
    • 2016-12-02
    • 2021-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多