【问题标题】:substring don't get a value when reading from a file从文件读取时子字符串没有值
【发布时间】:2021-11-19 20:44:26
【问题描述】:

我是 Java 新手,所以如果我问一些明显的问题,请原谅我。我知道你可能有更好的事情要做,但如果有人能指出我正确的方向,我会很感激。

我提取了 14 个子字符串,但最后 4 个字符串始终为空。 而且我不确定如何阅读以 55401 开头的下一行。 我可以如何提取任何子字符串有隐藏的限制吗?

我查看的文件:

  1. 55101BUYX SELLLX 0022200223210924
  2. 55201XQ 000897350210924 PARTNUMERXXX ZZ S000000V 0000000000
  3. 55301000000000000000000000000000000000000000000I
  4. 554012109240000000000462 2109270000000000000 2109280000000000000 2109290000000000000 2109300000000000000 2100010li>00000
  5. 554012110040000000000000 2110050000000000000 2110060000000000000 2110070000000000000 0000000000000000000000000000000000000
  6. 55701 JP010 ASDFGHJK
  7. 55901_output000000200000020000004000000000000020000001

从下面的代码我得到以下信息,字符串 6 和 7 没有得到值。

  1. 船舶 210924 |数量 000000462
  2. 船舶 210927 |数量 000000000
  3. 船舶 210928 |数量 000000000
  4. 船舶 210929 |数量 000000000
  5. 船舶 210930 |数量 000000000
  6. 船舶 |数量
  7. 船舶 |数量
public static void main(String[] args) throws IOException {

    File file = new File("C:\\Users\\Mail\\Desktop\\VDA Reader\\VDA.txt");
    Scanner scan = new Scanner(file);
    String input = "";
    String shipDate1 = "";
    String qty1 = "";
    String shipDate2 = "";
    String qty2 = "";
    String shipDate3 = "";
    String qty3 = "";
    String shipDate4 = "";
    String qty4 = "";
    String shipDate5 = "";
    String qty5 = "";
    String shipDate6 = "";
    String qty6 = "";
    String shipDate7 = "";
    String qty7 = "";
    String callOffs = "55401";
    //Scan next line if exists
    try {
        while (scan.hasNextLine()) {
            String outPut = scan.nextLine();
            if(outPut.startsWith(callOffs)){
                shipDate1 =     outPut.substring(5, 11);
                qty1 =          outPut.substring(15, 24);
                shipDate2 =     outPut.substring(25, 31);
                qty2 =          outPut.substring(35, 44);
                shipDate3 =     outPut.substring(45, 51);
                qty3 =          outPut.substring(55, 64);
                shipDate4 =     outPut.substring(65, 71);
                qty4 =          outPut.substring(75, 84);
                shipDate5 =     outPut.substring(85, 91);
                qty5 =          outPut.substring(95, 104);
                shipDate6 =     outPut.substring(105, 101);
                qty6 =          outPut.substring(115, 124);
            }
            if (outPut.startsWith(callOffs)){
                shipDate7 =     outPut.substring(5, 11);
                qty7 =          outPut.substring(15, 24);

            }
            input = input.concat(outPut + "\n");
        }
    }
    catch (Exception e){
    }
    scan.close();
    System.out.println("Ship "+shipDate1 + " | QTY " + qty1);
    System.out.println("Ship "+shipDate2 + " | QTY " + qty2);
    System.out.println("Ship "+shipDate3 + " | QTY " + qty3);
    System.out.println("Ship "+shipDate4 + " | QTY " + qty4);
    System.out.println("Ship "+shipDate5 + " | QTY " + qty5);
    System.out.println("Ship "+shipDate6 + " | QTY " + qty6);
    System.out.println("Ship "+shipDate7 + " | QTY " + qty7);

【问题讨论】:

  • 您的 cod 永远不会填写 shipDate6qty6shipDate7qty7,因为在线 shipDate6 = outPut.substring(105, 101); substring() 方法会抛出 IndexOutOfBoundsException,因为结束索引 ( 101) 小于起始索引 105。您永远不会看到此异常的任何痕迹,因为您的代码有助于捕获所有异常并忽略它们。

标签: java substring java.util.scanner


【解决方案1】:

首先,我建议使用适当的数据结构,这将使其更易于使用和阅读。 你需要上课,例如ShippingInformation。这个类有两个属性shippingDatequantity。这个类还应该包含一个接受这两个参数的构造函数。

public class ShippingInformation {
    private String shippingDate;
    private String quantity;

    public ShippingInformation(String shippingDate, String quantity) {
        this.shippingDate = shippingDate;
        this.quantity = quantity;
    }
    
    // Getter and Setter for both of the attributes
}

现在您不需要有 14 个字符串,其中 7 个包含相同类型的信息。 也是这样用String::substring,真的很难读。

您不需要检查同一行是否以55401 开头两次。

第七个条目不能填写,因为一行只有六个这样的数字。似乎您正试图用以55401 开头的第二行的第一个日期和数量来填充第七个,但您正试图在同一行上完成所有这些操作。

看下面的代码。它接收一行,删除55401 并将该行拆分为一个空格。您现在有一个包含六个元素的数组。这些可用于在循环中提取所需的信息。提取的信息会保存到一个列表中,以便您以后可以使用提取的信息。

使用此代码,您最后应该有 12 个输出。

    public static void main(String[] args) {
        List<ShippingInformation> shippings = new ArrayList();
        File file = new File("path");
        String callOffs = "55401";

        try(Scanner scan = new Scanner(file)) {
            while (scan.hasNextLine()) { // this loop automatically calls the next line, if there is a next line
                String line = scan.nextLine(); // get the next line
                if (line.startsWith(callOffs)) {
                    line = line.replace(callOffs, ""); // replace the value of callOffs
                    String[] split = line.split(" "); // split your line at a whitespace
                    for (String element : split) { // create a ShippingInformation for every eligible entry
                        shippings.add(new ShippingInformation(element.substring(0, 6), element.substring(10, 19)));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        for(ShippingsInformation shipping: shippings) {
            System.out.println("Ship " + shipping.getShippingDate() + " | QTY " + shipping.getQuantity());
        }
    }

【讨论】:

  • 非常感谢,我会在了解如何编写代码的情况下开始学习如何编写代码。我也想学习 :) 如何从 55401 的第二行获取数据?在我得到的文件中,我可以有几个相同的行 55401,但它们都遵循相同的规则,55401-DATE-QTY-separator x6
  • @Niklas 我不完全明白你想知道。我建议您在调用scan.nextLine() 后添加一条打印语句并打印该行。然后您将看到如何使用所有行。
  • 谢谢RatzzFatzz,我会努力学习你的方法,我想我了解它是如何制作的以及它是如何更好的,只需要了解它是如何工作的。我试图从客户那里读取不同的调用,文件每次都不同,但它仍然遵循一组规则。例如,55401 之后的前 6 个字符始终是日期等。我理解文件中的代码就像阅读 java 一样容易,但我需要将内容呈现给完全不了解文件的 ppl,比如我在java atm :)
猜你喜欢
  • 2012-10-03
  • 1970-01-01
  • 1970-01-01
  • 2018-08-22
  • 2017-06-25
  • 2019-05-23
相关资源
最近更新 更多