You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

本地到服务器文件拷贝正常,服务器到本地拷贝遇登录失败问题求助

问题描述

尝试将PDF文件从SMB服务器拷贝到本地文件夹时,持续遇到以下错误:

Logon failure: unknown user name or bad password.

对应的实现函数如下:

public void copyPasteFileFromNetwerkDriveToLocal(String source, String destFileUrl, String destFileName) {
    InputStream in = null;
    OutputStream out = null;
    try {
        
        NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("domain","user","password");
        String remoteDocUrl = "smb:"+source; //The shared directory to store pictures
        SmbFile remoteDocUrlFile = new SmbFile(remoteDocUrl, auth);
        remoteDocUrlFile.connect(); //Try to connect
        
        if (remoteDocUrlFile.exists()) {
            String remoteDocUrlAndName = "smb:"+source;
            SmbFile remoteDocFile = new SmbFile(remoteDocUrlAndName, auth);
            remoteDocFile.connect(); //Try to connect
            
            File localFile = new File(destFileUrl+destFileName);
            
            in = new BufferedInputStream(new SmbFileInputStream(remoteDocFile));
            out = new BufferedOutputStream(new FileOutputStream(localFile));

            byte[] buffer = new byte[4096];
            int len = 0; //Read length
            while ((len = in.read(buffer, 0, buffer.length)) != -1) {
                out.write(buffer, 0, len);
            }               
            
            out.flush(); //The refresh buffer output stream
        }
    }
    catch (Exception e) {
        String msg = "The error occurred: " + e.getLocalizedMessage();
        System.out.println(msg);
    }
    finally {
        try {
            if(out != null) {
                out.close();
            }
            if(in != null) {
                in.close();
            }
        }
        catch (Exception e) {}
    }       
} 

但使用相同用户名和密码,从本地到服务器的文件拷贝功能却可以正常运行,对应的函数如下:

public void copyPasteFileFromLocalToNetwerkDrive(String source, String destFileUrl, String destFileName) {
    InputStream in = null;
    OutputStream out = null;
    try {
        //Get a picture
        File localFile = new File(source);
        
        NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("domain","user","password");
        String remoteDocUrl = "smb:"+destFileUrl; //The shared directory to store pictures
        SmbFile remoteDocUrlFile = new SmbFile(remoteDocUrl, auth);
        remoteDocUrlFile.connect(); //Try to connect
        
        if (!remoteDocUrlFile.exists()) {
            //maak alle directories
            remoteDocUrlFile.mkdirs();
        }
        
        String remoteDocUrlAndName = "smb:"+destFileUrl+destFileName;
        SmbFile remoteDocFile = new SmbFile(remoteDocUrlAndName, auth);
        remoteDocFile.connect(); //Try to connect

        in = new BufferedInputStream(new FileInputStream(localFile));
        out = new BufferedOutputStream(new SmbFileOutputStream(remoteDocFile));

        byte[] buffer = new byte[4096];
        int len = 0; //Read length
        while ((len = in.read(buffer, 0, buffer.length)) != -1) {
            out.write(buffer, 0, len);
        }
        out.flush(); //The refresh buffer output stream
    }
    catch (Exception e) {
        String msg = "The error occurred: " + e.getLocalizedMessage();
        System.out.println(msg);
    }
    finally {
        try {
            if(out != null) {
                out.close();
            }
            if(in != null) {
                in.close();
            }
        }
        catch (Exception e) {}
    }       
}

请问哪里操作有误?


问题分析与解决

对比两个函数,核心问题出在从服务器到本地的函数中,source参数的路径拼接逻辑错误:

  1. 在copyPasteFileFromNetwerkDriveToLocal函数里,remoteDocUrl和remoteDocUrlAndName都直接拼接了smb:+source,如果source本身已经包含smb://前缀,就会生成smb:smb://xxx的非法路径,导致认证失败。而正常工作的copyPasteFileFromLocalToNetwerkDrive函数中,destFileUrl是不带smb:前缀的服务器共享目录路径,所以拼接逻辑是合法的。

另外还有两个冗余问题:

  • 重复创建了两个指向同一路径的SmbFile对象,完全可以复用第一个对象,避免重复连接。
  • 手动调用connect()是多余的,SmbFile在执行exists()、getInputStream()等操作时会自动建立连接。

修复后的函数示例:

public void copyPasteFileFromNetwerkDriveToLocal(String source, String destFileUrl, String destFileName) {
    InputStream in = null;
    OutputStream out = null;
    try {
        NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("domain","user","password");
        // 确保source是合法的SMB路径:如果不带smb前缀则添加,否则直接使用
        String remoteFilePath = source.startsWith("smb:") ? source : "smb:" + source;
        SmbFile remoteDocFile = new SmbFile(remoteFilePath, auth);
        
        if (remoteDocFile.exists()) {
            // 用File构造函数拼接本地路径,避免分隔符问题
            File localFile = new File(destFileUrl, destFileName);
            
            in = new BufferedInputStream(new SmbFileInputStream(remoteDocFile));
            out = new BufferedOutputStream(new FileOutputStream(localFile));

            byte[] buffer = new byte[4096];
            int len;
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
            }               
            out.flush();
        }
    } catch (Exception e) {
        System.out.println("错误发生: " + e.getLocalizedMessage());
    } finally {
        try {
            if(out != null) out.close();
            if(in != null) in.close();
        } catch (Exception e) {}
    }       
} 

额外注意事项:

  • 拼接本地路径时,优先使用new File(destFileUrl, destFileName)替代字符串拼接,避免因不同系统路径分隔符差异导致的错误。
  • 检查source参数的传入值,确认是否已经包含smb:前缀,这是导致认证报错的最直接原因。

内容的提问来源于Stack Exchange,提问作者Laurens Wolf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 20:20:26