java ftp 上传下载,当前文件格式错误或者数据损坏 / 读取FTP文件列表为null值,等待时间很长,且不报错

  • 上传下载相关问题

    • 检查vsftp服务器文件
      ftp上传上去的文件是否是正常文件,下载解压检查
    • 检查下载路径是否正确
      debug检查下载路径,下载路径不正确,下载后输出的文件也会报损坏或者格式错误
    • 若是上传至服务器的文件格式不正确,检查上传格式
      client.setFileType(FTP.BINARY_FILE_TYPE);
      Windows上传至Linux FTP服务文件模式是不一样的,在ftpclient登录后,设置文件类型。
    • 同样若是上传后格式正确,下载路径也是对的,检查下载时ftpclient设置的文件格式
      client.setFileType(FTP.BINARY_FILE_TYPE);
  • java 读取ftp文件问题

    • ftpclient.listNames(path) 读取不到ftp服务器上的文件(被动模式导致的问题)
      首先检查路径是不是对的,路径不对读个毛。
      然后检查vsftp服务器是什么模式,如果是被动模式的话,在login以后,加上ftpclient.enterRemotePassiveMode();设置被动模式
    • 被动模式下,根路径问题
      vsftp为被动模式情况下,设置的根路径,在ftpclient做操作时,不会生效(具体可以仔细研究为啥),相对路径读取时,依旧读取不到文件列表
      ftpclient.printWorkingDirectory获取到根路径,然后拼接到相对路径前即可获取到

    以上问题在主动模式下,正常情况下不会出现

  • changeWorkingDirectory不生效问题

    • 明明当前工作路径是根路径,就是无法使用changeWorkingDirectory切换到存在的路径下
      1、检查vsftp模式,被动模式下默认的根路径不会生效,可以ftpclient.printWorkingDirectory获取到根路径,然后拼接到需要切换的目录前,进行绝对路径的切换,相对路径切换不生效。
      2、ftpclient.enterRemotePassiveMode();设置被动模式,然后尝试(未进行验证),如果还是不行,那就绝对路径切换。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NoNonsense-FilePicker有如下特点: 1.可扩展以适应不同的数据源。 2.支持多选。 3.可以选择目录或者是文件。 4.可以在选择器中新建目录。 NoNonsense-FilePicker不只是另外一个文件选择器而已 我需要的是这样一个文件选择器: 1.容易扩展,文件来源既可以是本地sdcard,也可以是来自云端的dropboxapi。 2.可以在选择器中创建目录。 本项目具备上述的两个要求,同时很好的适配了平板和手机两种UI效果。项目的核心是在一个abstract 类中,因此你可以很方便的继承以实现自己需要的选择器。 项目本身已经包含了一个能够选择本地sdcard文件的实现,但你完全可以扩展实现一个文件列表来源于云端的选择器,比如Dropbox, ftp,ssh等。 选择器是基于activity,在屏幕较小的设备上全屏显示,而在较大的屏幕上则显示成dialog的方式,这个特性是系统主题中做到的,因此为activity选择一个正确的主题至关重要。 使用说明: 该库的核心思想是做到可扩展,但是你只是想选择sdcard中的文件,只需阅读关于如何使用sdcard文件选择器就可以了。 首选需要加上文件访问权限: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 将选择器的app注册到AndroidManifest.xml <activity android:name="com.nononsenseapps.filepicker.FilePickerActivity" android:label="@string/app_name" android:theme="@style/FilePicker.Theme"> <intent-filter> <action android:name="android.intent.action.GET_CONTENT"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> 在java代码中调用选择器: // This always works Intent i = newIntent(context, FilePickerActivity.class); // This works if you defined the intent filter // Intent i = new Intent(Intent.ACTION_GET_CONTENT); // Set these depending on your use case. These are the defaults. i.putExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, false); i.putExtra(FilePickerActivity.EXTRA_ALLOW_CREATE_DIR, false); i.putExtra(FilePickerActivity.EXTRA_MODE, FilePickerActivity.MODE_FILE); startActivityForResult(i, FILE_CODE); 获取选择的返回: @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode == FILE_CODE && resultCode == Activity.RESULT_OK) { if(data.getBooleanExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, false)) { // For JellyBean and above if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { ClipData clip = data.getClipData(); if(clip != null) { for(int i = 0; i < clip.getItemCount(); i++) { Uri uri = clip.getItemAt(i).getUri(); // Do something with the URI } } // For Ice Cream Sandwich } else{ ArrayList<String> paths = data.getStringArrayListExtra (FilePickerActivity.EXTRA_PATHS); if(paths != null) { for(String path: paths) { Uri uri = Uri.parse(path); // Do something with the URI } } } } else{ Uri uri = data.getData(); // Do something with the URI } } }
public class FTPUtil { private FTPClient ftpClient=null; private boolean result = false; private FileInputStream fis; String ftpHost = "10.16.111.111"; String port = 21 String ftpUserName = "ftpuser11; String ftpPassword = "1234561"; /** * 登录服务器 * @param ftpInfo * @return * @throws IOException */ public FTPClient login() throws IOException { ftpClient = new FTPClient(); ftpClient.connect(ftpHost); boolean login = ftpClient.login(ftpUserName,ftpPassword); int reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftpClient.disconnect(); } if(login){ System.out.println("ftp连接成功!"); }else{ System.out.println("ftp连接失败!"); } //ftpClient.setControlEncoding("GBK"); return ftpClient; } /** * 字符串作为文件上传指定目录 下 * @param content 源字符串 * @param uploadDir 上传目录 * @param ftpFileName 上传文件名称 * @throws Exception */ public void ftpUploadByText(String content ,String uploadDir,String ftpFileName) throws Exception{ try { ftpClient = this.login(); //创建目录 createDir(ftpClient,uploadDir); // 设置上传目录 这个也应该用配置文件读取 ftpClient.changeWorkingDirectory(uploadDir); ftpClient.setBufferSize(1024); ftpClient.setControlEncoding("GBK"); // 设置文件类型(二进制) ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); String fileName = new String(ftpFileName.getBytes("GBK"),"iso-8859-1"); OutputStream os = ftpClient.storeFileStream(fileName); byte[] bytes = content.getBytes(); os.write(bytes); os.flush(); os.close(); } catch (Exception e) { ftpClient.disconnect(); ftpClient = null; e.printStackTrace(); throw e; }finally{ ftpClient.disconnect(); ftpClient = null; } } /** * 移动文件 * @param ftpInfo * @return * @throws Exception */ public boolean moveFile(FTPInfo ftpInfo)throws Exception { boolean flag = false; try { ftpClient = this.login(); flag = this.moveFile(ftpClient, ftpInfo.getChangeWorkingDirectoryPath(), ftpInfo.getFilePath()); } catch (IOException e) { e.printStackTrace(); throw e; } finally { try { ftpClient.disconnect(); ftpClient = null; } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("关闭FTP连接发生异常!", e); }catch (Exception e) { e.printStackTrace(); throw e; } } return flag; } /** * 删除文件 * @param ftpInfo * @return * @throws Exception */ public boolean deleteFile(FTPInfo ftpInfo)throws Exception { boolean flag = false; try { ftpClient = this.login(); flag = this.deleteByFolder(ftpClient, ftpInfo.getChangeWorkingDirectoryPath()); } catch (IOException e) { e.printStackTrace(); throw e; } finally { try { ftpClient.disconnect(); ftpClient = null; } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("关闭FTP连接发生异常!", e); }catch (Exception e) { e.printStackTrace(); throw e; } } return flag; } /** * 实现文件的移动,这里做的是一个文件夹下的所有内容移动到新的文件, * 如果要做指定文件移动,加个判断判断文件名 * 如果不需要移动,只是需要文件重命名,可以使用ftp.rename(oleName,newName) * @param ftp * @param oldPath * @param newPath * @return */ public boolean moveFile(FTPClient ftp,String oldPath,String newPath){ boolean flag = false; try { ftp.changeWorkingDirectory(oldPath); ftp.enterLocalPassiveMode(); //获取文件数组 FTPFile[] files = ftp.listFiles(); //新文件夹不存在则创建 if(!ftp.changeWorkingDirectory(newPath)){ ftp.makeDirectory(newPath); } //回到原有工作目录 ftp.changeWorkingDirectory(oldPath); for (FTPFile file : files) { if(file.isDirectory()) { moveFile(ftp,oldPath+file.getName()+"/" ,newPath+file.getName()+"/"); }else{ //转存目录 flag = ftp.rename(oldPath+new String(file.getName().getBytes("GBK"),"ISO-8859-1"), newPath+"/"+new String(file.getName().getBytes("GBK"),"ISO-8859-1")); } if(flag){ System.out.println(file.getName()+"移动成功"); }else{ System.out.println(file.getName()+"移动失败"); } } ftp.removeDirectory(new String(oldPath.getBytes("GBK"),"ISO-8859-1")); } catch (Exception e) { e.printStackTrace(); System.out.println("移动文件失败"); } return flag; } /** * 删除FTP上指定文件夹下文件及其子文件方法,添加了对中文目录的支持 * @param ftp FTPClient对象 * @param FtpFolder 需要删除的文件夹 * @return */ public boolean deleteByFolder(FTPClient ftp,String FtpFolder){ boolean flag = false; try { ftp.changeWorkingDirectory(new String(FtpFolder.getBytes("GBK"),"ISO-8859-1")); ftp.enterLocalPassiveMode(); FTPFile[] files = ftp.listFiles(); for (FTPFile file : files) { //判断为文件则删除 if(file.isFile()){ ftp.deleteFile(FtpFolder+new String(file.getName().getBytes("GBK"),"ISO-8859-1")); } //判断是文件夹 if(file.isDirectory()){ String childPath = FtpFolder +file.getName()+ "/"; //递归删除子文件夹 deleteByFolder(ftp,childPath); } } //循环完成后删除文件夹 flag = ftp.removeDirectory(new String(FtpFolder.getBytes("GBK"),"ISO-8859-1")); if(flag){ System.out.println(FtpFolder+"文件夹删除成功"); }else{ System.out.println(FtpFolder+"文件夹删除成功"); } } catch (Exception e) { e.printStackTrace(); System.out.println("删除失败"); } return flag; } /** * 创建目录 * @param createpath * @param sftp */ public void createDir(FTPClient ftpClient,String createpath) throws Exception { try { if(ftpClient.changeWorkingDirectory(createpath)) { return; } String pathArry[] = createpath.split("/"); StringBuffer filePath = new StringBuffer("/"); for (String path : pathArry) { if (path.equals("")) { continue; } filePath.append(path + "/"); if(!ftpClient.changeWorkingDirectory(filePath.toString())) { ftpClient.makeDirectory(filePath.toString()); ftpClient.changeWorkingDirectory(filePath.toString()); } } ftpClient.changeWorkingDirectory(createpath); }catch (Exception e) { e.printStackTrace(); throw new Exception("创建路径错误:" + createpath); } } }
VS编写的FTP服务器软件,C#网络程序编程学习用。 代码: using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Net; using System.Net.Sockets; using System.Threading; using System.Windows.Forms; namespace FtpServer { public partial class FtpServerForm : Form { TcpListener myTcpListener = null; private Thread listenThread; // 保存用户名和密码 Dictionary users; public FtpServerForm() { InitializeComponent(); // 初始化用户名和密码 users = new Dictionary(); users.Add("admin", "admin"); // 设置默认的主目录 tbxFtpRoot.Text = "F:/MyFtpServerRoot/"; IPAddress[] ips = Dns.GetHostAddresses(""); tbxFtpServerIp.Text = ips[5].ToString(); tbxFtpServerPort.Text = "21"; lstboxStatus.Enabled = false; } // 启动服务器 private void btnFtpServerStartStop_Click(object sender, EventArgs e) { if (myTcpListener == null) { listenThread = new Thread(ListenClientConnect); listenThread.IsBackground = true; listenThread.Start(); lstboxStatus.Enabled = true; lstboxStatus.Items.Clear(); lstboxStatus.Items.Add("已经启动Ftp服务..."); btnFtpServerStartStop.Text = "停止"; } else { myTcpListener.Stop(); myTcpListener = null; listenThread.Abort(); lstboxStatus.Items.Add("Ftp服务已停止!"); lstboxStatus.TopIndex = lstboxStatus.Items.Count - 1; btnFtpServerStartStop.Text = "启动"; } } // 监听端口,处理客户端连接 private void ListenClientConnect() { myTcpListener = new TcpListener(IPAddress.Parse(tbxFtpServerIp.Text), int.Parse(tbxFtpServerPort.Text)); // 开始监听传入的请求 myTcpListener.Start(); AddInfo("启动FTP服务成功!"); AddInfo("Ftp服务器运行中...[点击”停止“按钮停止FTP服务]"); while (true) { try { // 接收连接请求 TcpClient tcpClient = myTcpListener.AcceptTcpClient(); AddInfo(string.Format("客户端({0})与本机({1})建立Ftp连接", tcpClient.Client.RemoteEndPoint, myTcpListener.LocalEndpoint)); User user = new User(); user.commandSession = new UserSeesion(tcpClient); user.workDir = tbxFtpRoot.Text; Thread t = new Thread(UserProcessing); t.IsBackground = true; t.Start(user); } catch { break; } } } // 处理客户端用户请求 private void UserProcessing(object obj) { User user = (User)obj; string sendString = "220 FTP Server v1.0"; RepleyCommandToUser(user, sendString); while (true) { string receiveString = null; try { // 读取客户端发来的请求信息 receiveString = user.commandSession.streamReader.ReadLine(); } catch(Exception ex) { if (user.commandSession.tcpClient.Connected == false) { AddInfo(string.Format("客户端({0}断开连接!)", user.commandSession.tcpClient.Client.RemoteEndPoint)); } else { AddInfo("接收命令失败!" + ex.Message); } break; } if (receiveString == null) { AddInfo("接收字符串为null,结束线程!"); break; } AddInfo(string.Format("来自{0}:[{1}]", user.commandSession.tcpClient.Client.RemoteEndPoint, receiveString)); // 分解客户端发来的控制信息中的命令和参数 string command = receiveString; string param = string.Empty; int index = receiveString.IndexOf(' '); if (index != -1) { command = receiveString.Substring(0, index).ToUpper(); param = receiveString.Substring(command.Length).Trim(); } // 处理不需登录即可响应的命令(这里只处理QUIT) if (command == "QUIT") { // 关闭TCP连接并释放与其关联的所有资源 user.commandSession.Close(); return; } else { switch (user.loginOK) { // 等待用户输入用户名: case 0: CommandUser(user, command, param); break; // 等待用户输入密码 case 1: CommandPassword(user, command, param); break; // 用户名和密码验证正确后登陆 case 2: switch (command) { case "CWD": CommandCWD(user, param); break; case "PWD": CommandPWD(user); break; case "PASV": CommandPASV(user); break; case "PORT": CommandPORT(user, param); break; case "LIST": CommandLIST(user, param); break; case "NLIST": CommandLIST(user, param); break; // 处理下载文件命令 case "RETR": CommandRETR(user, param); break; // 处理上传文件命令 case "STOR": CommandSTOR(user, param); break; // 处理删除命令 case "DELE": CommandDELE(user, param); break; // 使用Type命令在ASCII和二进制模式进行变换 case "TYPE": CommandTYPE(user, param); break; default: sendString = "502 command is not implemented."; RepleyCommandToUser(user, sendString); break; } break; } } } } // 想客户端返回响应码 private void RepleyCommandToUser(User user, string str) { try { user.commandSession.streamWriter.WriteLine(str); AddInfo(string.Format("向客户端({0})发送[{1}]", user.commandSession.tcpClient.Client.RemoteEndPoint, str)); } catch { AddInfo(string.Format("向客户端({0})发送信息失败", user.commandSession.tcpClient.Client.RemoteEndPoint)); } } // 向屏幕输出显示状态信息(这里使用了委托机制) private delegate void AddInfoDelegate(string str); private void AddInfo(string str) { // 如果调用AddInfo()方法的线程与创建ListView控件的线程不在一个线程时 // 此时利用委托在创建ListView的线程上调用 if (lstboxStatus.InvokeRequired == true) { AddInfoDelegate d = new AddInfoDelegate(AddInfo); this.Invoke(d, str); } else { lstboxStatus.Items.Add(str); lstboxStatus.TopIndex = lstboxStatus.Items.Count - 1; lstboxStatus.ClearSelected(); } } #region 处理各个命令 #region 登录过程,即用户身份验证过程 // 处理USER命令,接收用户名但不进行验证 private void CommandUser(User user, string command, string param) { string sendString = string.Empty; if (command == "USER") { sendString = "331 USER command OK, password required."; user.userName = param; // 设置loginOk=1为了确保后面紧接的要求输入密码 // 1表示已接收到用户名,等到接收密码 user.loginOK = 1; } else { sendString = "501 USER command syntax error."; } RepleyCommandToUser(user, sendString); } // 处理PASS命令,验证用户名和密码 private void CommandPassword(User user, string command, string param) { string sendString = string.Empty; if (command == "PASS") { string password = null; if (users.TryGetValue(user.userName, out password)) { if (password == param) { sendString = "230 User logged in success"; // 2表示登录成功 user.loginOK = 2; } else { sendString = "530 Password incorrect."; } } else { sendString = "530 User name or password incorrect."; } } else { sendString = "501 PASS command Syntax error."; } RepleyCommandToUser(user, sendString); // 用户当前工作目录 user.currentDir = user.workDir; } #endregion #region 文件管理命令 // 处理CWD命令,改变工作目录 private void CommandCWD(User user, string temp) { string sendString = string.Empty; try { string dir = user.workDir.TrimEnd('/') + temp; // 是否为当前目录的子目录,且不包含父目录名称 if (Directory.Exists(dir)) { user.currentDir = dir; sendString = "250 Directory changed to '" + dir + "' successfully"; } else { sendString = "550 Directory '" + dir + "' does not exist"; } } catch { sendString = "502 Directory changed unsuccessfully"; } RepleyCommandToUser(user,sendString); } // 处理PWD命令,显示工作目录 private void CommandPWD(User user) { string sendString = string.Empty; sendString = "257 '" + user.currentDir + "' is the current directory"; RepleyCommandToUser(user, sendString); } // 处理LIST/NLIST命令,想客户端发送当前或指定目录下的所有文件名和子目录名 private void CommandLIST(User user, string parameter) { string sendString = string.Empty; DateTimeFormatInfo dateTimeFormat = new CultureInfo("en-US", true).DateTimeFormat; // 得到目录列表 string[] dir = Directory.GetDirectories(user.currentDir); if (string.IsNullOrEmpty(parameter) == false) { if (Directory.Exists(user.currentDir + parameter)) { dir = Directory.GetDirectories(user.currentDir + parameter); } else { string s = user.currentDir.TrimEnd('/'); user.currentDir = s.Substring(0, s.LastIndexOf("/") + 1); } } for (int i = 0; i < dir.Length; i++) { string folderName = Path.GetFileName(dir[i]); DirectoryInfo d = new DirectoryInfo(dir[i]); // 按下面的格式输出目录列表 sendString += @"dwr-\t" + Dns.GetHostName() + "\t" + dateTimeFormat.GetAbbreviatedMonthName(d.CreationTime.Month) + d.CreationTime.ToString(" dd yyyy") + "\t" + folderName + Environment.NewLine; } // 得到文件列表 string[] files = Directory.GetFiles(user.currentDir); if (string.IsNullOrEmpty(parameter) == false) { if (Directory.Exists(user.currentDir + parameter + "/")) { files = Directory.GetFiles(user.currentDir + parameter + "/"); } } for (int i = 0; i 1024的随机端口 // 下面这个运算算法只是为了得到一个大于1024的端口 port = random1 << 8 | random2; try { user.dataListener = new TcpListener(localip, port); AddInfo("TCP 数据连接已打开(被动模式)--" + localip.ToString() + ":" + port); } catch { continue; } user.isPassive = true; string temp = localip.ToString().Replace('.', ','); // 必须把端口号IP地址告诉客户端,客户端接收到响应命令后, // 再通过新的端口连接服务器的端口P,然后进行文件数据传输 sendString = "227 Entering Passive Mode(" + temp + "," + random1 + "," + random2 + ")"; RepleyCommandToUser(user, sendString); user.dataListener.Start(); break; } } // 处理PORT命令,使用主动模式进行传输 private void CommandPORT(User user, string portstring) { // 主动模式时,客户端必须告知服务器接收数据的端口号,PORT 命令格式为:PORT address // address参数的格式为i1、i2、i3、i4、p1、p2,其中i1、i2、i3、i4表示IP地址 // 下面通过.字符串来组合这四个参数得到IP地址 // p1、p2表示端口号,下面通过int.Parse(temp[4]) << 8) | int.Parse(temp[5] // 这个算法来获得一个大于1024的端口来发送给服务器 string sendString = string.Empty; string[] temp = portstring.Split(','); string ipString = "" + temp[0] + "." + temp[1] + "." + temp[2] + "." + temp[3]; // 客户端发出PORT命令把客户端的IP地址和随机的端口告诉服务器 int portNum = (int.Parse(temp[4]) < 0) { user.dataSession.binaryWriter.Write(bytes, 0, count); user.dataSession.binaryWriter.Flush(); count = binaryReader.Read(bytes, 0, bytes.Length); } } else { StreamReader streamReader = new StreamReader(fs); while (streamReader.Peek() > -1) { user.dataSession.streamWriter.WriteLine(streamReader.ReadLine()); } } AddInfo("...]发送完毕!"); } finally { user.dataSession.Close(); fs.Close(); } } // 使用数据连接接收文件流(客户端发送上传文件功能) private void ReadFileByUserSession(User user, FileStream fs) { AddInfo("接收用户上传数据文件流):[..."); try { if (user.isBinary) { byte[] bytes = new byte[1024]; BinaryWriter binaryWriter = new BinaryWriter(fs); int count = user.dataSession.binaryReader.Read(bytes, 0, bytes.Length); while (count > 0) { binaryWriter.Write(bytes, 0, count); binaryWriter.Flush(); count = user.dataSession.binaryReader.Read(bytes, 0, bytes.Length); } } else { StreamWriter streamWriter = new StreamWriter(fs); while (user.dataSession.streamReader.Peek() > -1) { streamWriter.Write(user.dataSession.streamReader.ReadLine()); streamWriter.Flush(); } } AddInfo("...]接收完毕"); } finally { user.dataSession.Close(); fs.Close(); } } private void label3_Click(object sender, EventArgs e) { } } }
Java中使用FTP下载Word文件,需要注意以下几点,以保证文件名和文件内容不会出现乱码: 1. 指定FTP文件传输格式:在下载文件之前,需要设置FTP的传输格式为二进制传输格式,以保证文件内容不会出现乱码。可以使用FTPClient的setFileType方法设置传输格式为二进制传输格式: ``` FTPClient ftp = new FTPClient(); ftp.connect(server, port); ftp.login(user, password); ftp.setFileType(FTP.BINARY_FILE_TYPE); ``` 2. 指定文件名编码格式:在下载文件之前,需要指定要下载的文件名编码格式,以保证文件名不会出现乱码。可以使用FTPClient的setControlEncoding方法指定文件名编码格式: ``` FTPClient ftp = new FTPClient(); ftp.connect(server, port); ftp.login(user, password); ftp.setFileType(FTP.BINARY_FILE_TYPE); ftp.setControlEncoding("UTF-8"); ``` 3. 指定本地文件名编码格式:在将文件保存到本地磁盘时,需要指定本地文件名编码格式,以保证文件名不会出现乱码。可以使用Java的URLDecoder解码方法对文件名进行解码: ``` InputStream in = ftp.retrieveFileStream(remoteFilePath); OutputStream out = new FileOutputStream(URLDecoder.decode(localFilePath, "UTF-8")); ``` 4. 使用合适的文本编码格式:如果下载的文件是Word文档,需要使用合适的文本编码格式来读取文件内容,以保证文件内容不会出现乱码。可以使用Java的FileInputStream和InputStreamReader类来读取文件内容,并指定合适的文本编码格式: ``` FileInputStream fis = new FileInputStream(localFilePath); InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); BufferedReader br = new BufferedReader(isr); String line; while ((line = br.readLine()) != null) { // 处理文件内容 } ``` 综上所述,可以使用上述方法来实现在Java中下载FTP上的Word文件,同时保证文件名和文件内容不会出现乱码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值