怎么在hdfs上下载文件传给前端

我现在想从hdfs上获取文件直接将获取到的文件返回给前端,请问要怎么实现? 文件不能存放到本地路径
java环境

String fileName = "xxx";
response.reset();
        response.setContentType("application/x-msdownload");
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(), "ISO-8859-1"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        try (
                BufferedInputStream bis = new BufferedInputStream("xxx");
                // 输出流
                BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream())
        ) {
            byte[] buff = new byte[1024];
            int len = 0;
            while ((len = bis.read(buff)) > 0) {
                bos.write(buff, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

什么类型的文件,文本数据的话可以后端先读取,然后传给前端文本数据。音视频等二进制还是传本地路径哇!
参考这个传二进制的,看对你有帮助没:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;

public class FileController {
    public void getBinaryFileFromHdfs(HttpServletResponse response) throws IOException {
        // Set up Hadoop HDFS Configuration
        Configuration conf = new Configuration();
        conf.set("fs.defaultFS", "hdfs://hdfs-server:9000");

        // Create Hadoop HDFS FileSystem
        FileSystem fs = FileSystem.get(conf);

        // Open the file on HDFS
        Path filePath = new Path("/path/to/file.mp4");
        InputStream in = fs.open(filePath);

        // Set the response headers
        response.setContentType("video/mp4");
        response.setHeader("Content-Disposition", "attachment; filename=file.mp4");

        // Write the file to the response body
        ServletOutputStream out = response.getOutputStream();
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = in.read(buffer)) != -1) {
            out.write(buffer, 0, bytesRead);
        }

        // Close the file and output stream
        in.close();
        out.close();
    }
}

在Java环境下,你可以使用Apache Hadoop的HDFS Java API来从HDFS上获取文件。

首先,你需要准备一个HDFS的配置文件,包含HDFS的主机地址、端口号等信息。然后,使用HDFS Java API的FileSystem类,调用它的get()方法即可从HDFS上获取文件。

例如,你可以使用以下代码从HDFS上获取文件:

Configuration conf = new Configuration();
conf.addResource(new Path("hdfs-site.xml"));
FileSystem fs = FileSystem.get(conf);
Path srcPath = new Path("/path/to/file");
FSDataInputStream in = fs.open(srcPath);

获取到文之后,你可以通过将文件数据读入内存或者将文件数据写入本地文件来获取文件内容。例如,你可以使用以下代码将文件数据读入内存:

byte[] buffer = new byte[1024];
ByteArrayOutputStream out = new ByteArrayOutputStream();
int len = 0;
while((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
byte[] data = out.toByteArray();

或者使用以下代码将文件数据写入本地文件:

FileOutputStream out = new FileOutputStream("local-file.txt");
int len = 0;
while((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
out.close();

最后,你可以将文件数据作为HTTP响应的内容返回给前端。例如,你可以使用Java Servlet或者Spring MVC等框架来处理HTTP请求和响应。

在这里,你可以使用HttpServletResponse对象的getOutputStream()方法获取输出流,然后将文件数据写入输出流即可。例如:

HttpServletResponse response = ...;
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=file.txt");
OutputStream out = response.getOutputStream();
out.write(data);
out.flush();
out.close();

注意:如果文件较大,你可能需要考虑使用流式读取和写入的方式来处理文件数据,以避免内存溢出的问题。例如,你可以使用BufferedInputStream和BufferedOutputStream缓冲流来读取和写入文件数据,以提升读写效率。

例如,你可以使用以下代码将文件数据读入内存:

InputStream in = new BufferedInputStream(fs.open(srcPath));
ByteArrayOutputStream out = new ByteArrayOutputStream();
int len = 0;
while((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
byte[] data = out.toByteArray();


或者使用以下代码将文件数据写入本地文件:

OutputStream out = new BufferedOutputStream(new FileOutputStream("local-file.txt"));
int len = 0;
while((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
out.close();= in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
byte[] data = out.toByteArray();


前端可以表格的形式展现

思路很简单,java 是可以通过FSDataInputStream 来读取hdfs文件,
当然也可以用get的方式把文件get到本地
你需要明确的是,前端如何接收你的文件,
以下是一个读取案例

其实读取到了数据就可以操作了,你可以把读取到数据封装到 list 或者 封装成json对象 用于和前端交互

import java.io.File;
import java.io.IOException;

public class HdfsTest {
    public static void main(String[] args) throws IOException {
        readFileToConsole("/a.txt");

    }

    //    读取hdfs文件系统中的文件
    private static void readFileToConsole(String path) throws IOException {
//        获取配置
        Configuration conf = new Configuration();
//        配置
        conf.set("fs.defaultFS","hdfs://172.27.66.46:9000");
//        获取hdfs文件系统的操作对象
        FileSystem fs = FileSystem.get(conf);
//        具体的对文件系统的操作
        FSDataInputStream fsDataInputStream = fs.open(new Path(path));
        IOUtils.copyBytes(fsDataInputStream,System.out,4096,true);


    }
}



public void download(HttpServletRequest request, HttpServletResponse response) {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            response.addHeader("Content-Disposition", "attachment;fileName=" + new String("file.getName()".getBytes("UTF-8"),"iso-8859-1"));
            URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
            URL url = new URL("路径");
            inputStream = url.openStream();
            outputStream = response.getOutputStream();
            byte[] buf = new byte[1024];
            int len;
            while ((len = inputStream.read(buf)) > 0) {
                outputStream.write(buf, 0, len);
            }
            response.flushBuffer();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

可以使用 Apache Hadoop 客户端程序来从 HDFS 中读取文件。需要先在 pom.xml 中添加 Apache Hadoop 的依赖项:

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-client</artifactId>
    <version>3.3.0</version>
</dependency>

然后可以使用以下代码读取 HDFS 中的文件:

Configuration configuration = new Configuration();
FileSystem hdfs = FileSystem.get(configuration);
Path path = new Path("/path/to/file.txt");
FSDataInputStream inputStream = hdfs.open(path);

接下来,可以使用 Java 的输入/输出流 API 从 FSDataInputStream 中读取文件内容。

若要将文件直接返回给前端,可以将文件内容写入 HTTP 响应流,并将响应头设置为“Content-Type”为文件的 MIME 类型,以便浏览器正确地解析文件:

response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=file.pdf");

OutputStream outputStream = response.getOutputStream();
IOUtils.copy(inputStream, outputStream);
outputStream.flush();

仅供参考,望采纳,谢谢。

上传下载我都写了,以流的形式

public class HOFSop {
    public static void main(String[] args) throws Exception {

       hdfsWriteFile("C:\\Users\\Administrator\\IdeaProjects\\hadoopStu\\resource\\helloworld.txt",
                "hdfs://192.168.153.135:9000/",
              "hdfs://192.168.153.135:9000/input/ab.txt");

//
//                     hdfsReadFile("hdfs://192.168.153.135:9000/input/ab.txt",
//                             "hdfs://192.168.153.135:9000/",
//                             "C:\\ab.txt");

   }

    public static void hdfsReadFile(String hdfsFile,
                                    String hdfsUrl,String fileName) throws Exception {
        Configuration cfg = new Configuration();
        cfg.set("fs.defaultFS", hdfsUrl);
        FileSystem fileSystem = FileSystem.get(cfg);

        if(! fileSystem.exists(new Path(hdfsFile))){
            throw  new Exception("要下载的文件不存在");
        }
        try {
            // 读取操作,从HDFS指定的文件读取数据对象
            FSDataInputStream fsdiStream = fileSystem.open(new Path(hdfsFile));
            try {
                // 将数据输出到本地文件的流对象
                FileOutputStream fileOutputStream = new FileOutputStream(fileName);
                try {
                    byte[] buffer = new byte[2048];
                    int count = fsdiStream.read(buffer, 0, 2048);
                    while (count>0){
                        fileOutputStream.write(buffer,0,count);
                        count=fsdiStream.read(buffer,0,2048);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                     fileOutputStream.close();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }finally {
                fsdiStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
    }

    public static void hdfsWriteFile(String fileName,
                                     String hdfsUrl,String hdfsFile) throws Exception {
        Configuration cfg = new Configuration();
        cfg.set("fs.defaultFS", hdfsUrl);
        FileSystem fileSystem = FileSystem.get(cfg);
        if (fileSystem.exists(new Path(hdfsFile))) {
            throw new Exception("目标文件已经存在");
        }
//        File file = new File(fileName);

        try {
            //输出流对象,将数据输出到HDFS文件系统
            FSDataOutputStream fsDataOutputStream = fileSystem.create(new Path(hdfsFile));
            try {
                //输入流对象,将本地要上传的文件读取到内存中
                FileInputStream fileInputStream = new FileInputStream(fileName);

                try {
                    byte[] buffer = new byte[2048]; //缓存
                    int count = fileInputStream.read(buffer, 0, 2048);
                    while (count>0){
                        fsDataOutputStream.write(buffer,0,count); //输出操作
                        count=fileInputStream.read(buffer,0,2048);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    fileInputStream.close();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            finally {
                fsDataOutputStream.close();
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}


首先需要使用 Apache Hadoop 的 FileSystem 类来连接到 HDFS。

然后可以使用 FileSystem 类的 open 方法来打开 HDFS 上的文件,并使用 IOUtils 类的 copyBytes 方法将文件的内容复制到输出流中。

最后可以使用 Servlet 的 setContentType 和 setContentLength 方法来设置响应头,并使用 OutputStream 将文件内容写入响应输出流中,以便前端可以下载该文件。

import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

public class FileDownloadServlet extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    String filePath = "/path/to/file.txt";
    Configuration conf = new Configuration();
    FileSystem fs = FileSystem.get(conf);
    Path path = new Path(filePath);
    if (!fs.exists(path)) {
      response.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }
    response.setContentType("text/plain");
    response.setContentLength((int) fs.getFileStatus(path).getLen());
    OutputStream os = response.getOutputStream();
    IOUtils.copyBytes(fs.open(path), os, conf);
  }
}