简体   繁体   English

Java:顺序排序名称并保存到随机访问文件中

[英]Java: Sequential sorting names and saving into a Random Access File

I am trying to make a program where I can add a name and it's supposed to be saved in a RandomAccessFile , (alphabetically). 我正在尝试创建一个程序,我可以添加一个名称,它应该保存在RandomAccessFile中(按字母顺序排列)。 Whenever I add a name it gets saved in a file, it's supposed to have at the end the next corresponding position for the next name. 每当我添加一个名称,它就会保存在一个文件中,它应该在下一个名称的下一个相应位置结束。 I'm having problems with the saving whenever I add a name with starting with A, then I add a name with C, and if I where to add a name starting with B it's not pointing me in the right alphabetical order. 每当我添加一个以A开头的名字时,我都会遇到保存问题,然后我用C添加一个名字,如果我在哪里添加一个以B开头的名字,那么它并没有按照正确的字母顺序指向我。

Here is what an example of what the program should do: 这是程序应该做的一个例子:

I add a name starting with A. 我添加一个以A开头的名字。

Numbers on "left" side are just where the next name start, Numbers on "right" side are the pointers to the next name “左”侧的数字正好是下一个名称的开头,“右”侧的数字是指向下一个名称的指针

[0]-----A----[-1] ----------- the "-1" pointer means its the end of the list [0] ----- A ---- [ - 1] -----------“-1”指针表示其列表的结尾

I add a name starting with C. 我添加一个以C开头的名字。

[0]-----A----[100] ------- the "100" pointer means that the next name "C" start on byte 100 [0] ----- A ---- [100] -------“100”指针表示下一个名称“C”从字节100开始

[100]---C----[-1] --------- end of the list pointer, notice how A no longer has the "-1" pointer [100] --- C ---- [ - 1] ---------列表指针结束,注意A如何不再有“-1”指针

I add a name starting with B. 我添加一个以B开头的名字。

[0]-----A----[200] ------ "A" no longer points to 100 because the next letter should be "B" [0] ----- A ---- [200] ------“A”不再指向100,因为下一个字母应为“B”

[100]---C----[-1] -------- -1 still means that "C" is the end of the list pointer [100] --- C ---- [ - 1] -------- -1仍然意味着“C”是列表指针的结尾

[200]---B----[100] --------- "B" is pointing at "C" because the next letter after [200] --- B ---- [100] ---------“B”指向“C”因为下一个字母后

Here is my code so far, but I'm missing the part where a name that belongs in the middle of the list is added. 到目前为止,这是我的代码,但是我错过了添加属于列表中间名称的部分。

public boolean add(String name, String lastName, String telf) { public boolean add(String name,String lastName,String telf){

    try {
        fileSize = file.length();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    if (fileSize == 0) { //must be a new entry

        try {

            byte entry[] = new byte[sizeEntry];  // size of each entry
            file.write(entry);
            file.seek(file.getFilePointer() - sizeEntry);

            file.writeUTF(name);   //name gets saved
            file.writeUTF(lastName);// last name gets saved
            file.writeUTF(telf);    // telf gets saved
            file.writeUTF("N");     // deleted "Y" or "N" gets saved
            file.writeUTF("-1");    // pointer gets saved

        } catch (IOException e) {
            System.out.println("Error at saving....");
            e.printStackTrace();
        }

    } else {
        pPresent= 0;     //variable for the pointer reading
        pPrevious= 0; // variable for the pointer read

        try {
            file.seek(0); //start reading at the top
            do {
                pPresent= file.getFilePointer();//saves present pointer
                file.seek(pPresent);//seeks to present pointer
                nameRead = file.readUTF();  //reads name
                file.readUTF();  //reads last name
                file.readUTF();  //reads telf
                file.readUTF();  //reads deleted?
                pNext= Long.parseLong(file.readUTF()); // reads the next pointer

                int comparison= name.compareTo(nameRead);
                if (comparison< 0) {

                    //enters here if the new entry goes before the present entry
                    if (pNext!= -1) {
                        file.seek(pNext);//enters here if pointer is not at end of list
                    } else {
                        try {// proceeds to writing a new entry 

                            file.seek(file.length()); //goes to the end of the file
                            byte entry[] = new byte[sizeEntry];
                            file.write(entry);
                            file.seek(file.getFilePointer() - sizeEntry);

                            file.writeUTF(name);
                            file.writeUTF(lastname);
                            file.writeUTF(telf);
                            file.writeUTF("N");
                            file.writeUTF(Long.toString(pPrevious));//writes the previous pointer

                            file.seek(pPrevious);//seeks to the previous entry
                            file.readUTF();//reads name
                            file.readUTF();//reads lastname
                            file.readUTF();//reads telf
                            file.readUTF();//reads deleted?
                            file.writeUTF(Long.toString(pPrevious));//overwrites the new previous

                        } catch (IOException e) {
                            System.out.println("Error at saving...");
                            e.printStackTrace();
                        }
                        break;//exits
                    }
                } else {//enteres here if the entry is bigger than the present

                    if (pNext!= -1) {
                        file.seek(pNext);
                    } else {
                        try {

                            pPresent= file.length()-sizeEntry;//saves present entry
                            file.seek(pPrevious); //seeks to previous entry
                            file.readUTF();//reads name
                            file.readUTF();//reads last name
                            file.readUTF();//reads telf
                            file.readUTF();//reads deleted
                            file.writeUTF(Long.toString(pPresent+100));//overwrites the next pointer

                            file.seek(file.length());//seeks at the end
                            byte entry[] = new byte[sizeEntry];//creates a new entry
                            file.write(entry);
                            file.seek(file.getFilePointer() - sizeEntry);

                            file.writeUTF(name);//writes name
                            file.writeUTF(lastname);//writes lastname
                            file.writeUTF(telf);//writes telf
                            file.writeUTF("N");//writes deleted
                            file.writeUTF(Long.toString(pNext));//writes next pointer

                        } catch (IOException e) {
                            System.out.println("Error at saving...");
                            e.printStackTrace();
                        }
                        break;//exits
                    }
                }
                pPresent= file.getFilePointer();//present pointer read
                pPrevious= pPresent;//present pointer becomes previous
            } while (true);


        } catch (IOException e) {

            System.out.println("Error at saving....");
            e.printStackTrace();
        }
    }
    return false;
}

I hope you guys understand the idea of the program a little better now with the source code. 我希望你们现在用源代码了解程序的想法。 The part I don't know how to do is where I add a entry that belongs in the middle of the list. 我不知道该怎么做的部分是我添加一个属于列表中间的条目。 Remember that the order of the names dont change only the pointers pointing to the next do. 请记住,名称的顺序不会只改变指向下一个指针的指针。

Finding the insertion point will require traversing the list, which in turn requires a disk access for every single name. 查找插入点将需要遍历列表,这又需要每个名称的磁盘访问权限。 Assuming you have 1 million names, and a typical disk access time of 10 ms, inserting a single name would take about 3 hours. 假设您有100万个名称,典型的磁盘访问时间为10毫秒,插入一个名称大约需要3个小时。 Put differently, linked lists are an extremly unsuitable data structure for storing data on disk. 换句话说,链表是用于在磁盘上存储数据的极不适合的数据结构。

A reasonable data structure such as a B-Tree would permit lookup and insertion among 1 million names in as little as 3 disk accesses. 合理的数据结构(如B-Tree)允许在少至3个磁盘访问中查找和插入100万个名称。

Yo have to develop a method that calculates the pointer, I develop a code a few days ago: 你必须开发一个计算指针的方法,我几天前开发了一个代码:

public int getNext(String lastName){

    int auxNext=0;
    int auxActual=0;
    byte[] relleno= new byte[100];

    try{

        int Next=-1;

        while(auxNext!=-1){                                             

            auxActual=auxNext;              
            myRaf.seek(auxNext);
            String auxPreviousLastName=myRaf.readUTF();

            auxNext=Integer.valueOf(myRaf.readUTF());

            if(auxNext!=-1){

                myRaf.seek(auxNext);
                String auxApellido=myRaf.readUTF();

                String aux=myRaf.readUTF();

                if(lastName.compareTo(auxLastName)<0){                          

                    Next=auxNext;                                       
                    myRaf.seek(auxActual);                                  
                    myRaf.write(relleno);
                    myRaf.seek(auxActual);
                    myRaf.writeUTF(auxPreviousLastName);                        
                    myRaf.writeUTF(String.valueOf(myRaf.length()));
                    return Next;                                            

                }

            }else{                                                          

                updateEnds();
                return -1;                                                  

            }

        }

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

    return -1;

}

public void updateEnds(){       //This method search the last register, and updates that reference

    byte[] relleno= new byte[100];

    try {
        for (int i = 0; i < myRaf.length(); i+=100) {               

            myRaf.seek(i);
            String auxLastName=myRaf.readUTF();             
            String next=myRaf.readUTF();

            if (next.equals("-1")) {                                    

                myRaf.seek(i);                                          
                myRaf.write(relleno);                                   
                myRaf.seek(i);                                          
                myRaf.writeUTF(auxLastName);
                myRaf.writeUTF(String.valueOf(myRaf.length())); 


            }

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

}

PD, Sorry, I don't write in english as well as you. 对不起,我不会用英语和你一起写。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM