【问题标题】:Getting NullPointerException with SmbFileInputStream使用 SmbFileInputStream 获取 NullPointerException
【发布时间】:2018-11-16 10:24:14
【问题描述】:

试图修改另一台机器上的excel。传递 IP 地址、用户名、密码和文件路径来访问和修改文件,但在 new SmbFileInputStream(sFile) 处得到 NullPointerException。这是什么原因?

NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("domin", "username", "password");
                String path = "smb:\\\\<IPaddress>\\C$\\<FolderName>\\File%20-%20Input.xlsx";
                SmbFile sFile = new SmbFile(path, auth);



                try {
                    SmbFileInputStream inputStream = new SmbFileInputStream(sFile);
                    Workbook workbook = WorkbookFactory.create(inputStream);

                    Sheet sheet = workbook.getSheetAt(0);
                    int rowCount = sheet.getLastRowNum(),i=0;
                    Cell cell;
                    for(ForemostReservedDataDO obj : unsavedRecords){
                        i++;
                        Row row = sheet.createRow(rowCount+i);
                        cell = row.createCell(0);
                        cell.setCellValue(obj.getPolicyNum());
                        cell = row.createCell(1);
                        cell.setCellValue("Recreational Value");
                    }
                    inputStream.close();

                    SmbFileOutputStream sfos = new SmbFileOutputStream(sFile);
                    workbook.write(sfos);
                    workbook.close();
                    sfos.close();

                } catch (EncryptedDocumentException | InvalidFormatException | IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

全栈

SEVERE: Servlet.service() for servlet [spring-dispatcher] in context with path [/Foremost] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
    at jcifs.smb.ServerMessageBlock.writeString(ServerMessageBlock.java:213)
    at jcifs.smb.ServerMessageBlock.writeString(ServerMessageBlock.java:202)
    at jcifs.smb.SmbComNTCreateAndX.writeBytesWireFormat(SmbComNTCreateAndX.java:170)
    at jcifs.smb.AndXServerMessageBlock.writeAndXWireFormat(AndXServerMessageBlock.java:101)
    at jcifs.smb.AndXServerMessageBlock.encode(AndXServerMessageBlock.java:65)
    at jcifs.smb.SmbTransport.doSend(SmbTransport.java:439)
    at jcifs.util.transport.Transport.sendrecv(Transport.java:67)
    at jcifs.smb.SmbTransport.send(SmbTransport.java:655)
    at jcifs.smb.SmbSession.send(SmbSession.java:238)
    at jcifs.smb.SmbTree.send(SmbTree.java:119)
    at jcifs.smb.SmbFile.send(SmbFile.java:775)
    at jcifs.smb.SmbFile.open0(SmbFile.java:989)
    at jcifs.smb.SmbFile.open(SmbFile.java:1006)
    at jcifs.smb.SmbFileInputStream.<init>(SmbFileInputStream.java:73)
    at jcifs.smb.SmbFileInputStream.<init>(SmbFileInputStream.java:65)
    at com.Foremost.Controllers.DataDownController.saveReservedData(DataDownController.java:217)

【问题讨论】:

  • 请将 NPE 的完整 Stacktrace 添加到您的问题中。
  • 感谢 Stacktrace。您使用的是哪个版本的 JCIFS?
  • jcifs 版本为 1.3.17
  • 谢谢(您应该将其添加到问题中)。这是一个非常的旧版本,你应该升级到最新版本:mvnrepository.com/artifact/org.codelibs/jcifs/2.1.3(注意:新 groupId)
  • 抱歉,下次一定会提版本。您能否根据我的要求提供最新版本(2.1.3)的任何示例代码。我写的是最新的 jar 编译错误(因为这些是不推荐使用的方法)

标签: java nullpointerexception jcifs


【解决方案1】:

您的 JCIFS 版本似乎已过时并且与远程系统不兼容。升级到最新的 JCIFS(当前版本:2.1.3,https://github.com/codelibs/jcifs)或 jcifs-ng (https://github.com/AgNO3/jcifs-ng),链接的 JCIFS 现在是其中的一个分支。

下面是一些关于如何使用 jcifs-ng 通过 SMB 读取文件的示例代码:

String fileUrl = "smb://netserver/some/path/to/file.xls";

Properties cifsProps = new Properties();
cifsProps.setProperty("jcifs.smb.client.domain", "my.domain.int");
cifsProps.setProperty("jcifs.smb.client.username", USER_NAME);
cifsProps.setProperty("jcifs.smb.client.password", PASSWORD);

Configuration config = new PropertyConfiguration(cifsProps);
BaseContext context = new BaseContext(config);
SmbResource resource = context.get(fileUrl);

if (!(resource instanceof SmbFile)) {
    throw new CIFSException("File URL does not point to a file on a network share");
}

try (InputStream in = ((SmbFile) resource).getInputStream()) {
    // TODO read from in
} finally {
    context.close();
}

对于写一个文件,好吧,我想你会想出来的:-)

【讨论】:

  • 太好了,谢谢@Florian。有一个小问题,我的是 jdk1.7 我需要 JDK 1.8 用于 JCIFS 2.1.3。我正在尝试升级我的项目。无论如何,非常感谢。完成后,我将为您的答案投票。
  • 我认为他们最近删除了 1.7 支持。也许你可以例如使用 jcifs-ng 2.0.5,它应该可以在 1.7 上正常工作,并且仍然足够新。
  • 是的,我尝试使用 jcifs-ng 2.0.5 获取 jcifs.smb.SmbAuthException:访问被拒绝。但是对于同一个用户,我可以直接打开和修改。会有什么问题?
  • 拒绝访问,创建新问题。 stackoverflow.com/questions/53387310/…
  • 有一个疑问,是否必须共享我要访问的文件夹?我们不能通过共享连接吗?
【解决方案2】:

很可能,问题在于您的sFile 对象是null

检查您提供的文件的路径。

【讨论】:

  • 嗯,这也是我的第一个想法,但作为sFile = new SmbFile(...),如果没有删除关键的代码行,那么如果该行成功,它就不可能是null
  • 不,如果路径不正确,在这种情况下,sFile 可能为空。能不能放个调试器检查一下sFile是否为null?
  • 我不是 OP。不,如果 sFile 用new SmbFile(...) 初始化,它可以为空。在使用类的新实例初始化后,任何 Java 引用都不能为空,除非构造函数调用因异常而失败(然后会导致 OP 报告的另一行出现异常)。
  • sFile is not null check in debug.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-20
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
  • 1970-01-01
相关资源
最近更新 更多