मुझे उपयोगकर्ता से इनपुट में समस्या है। मुझे उपयोगकर्ता से बाइनरी फ़ाइल में इनपुट सहेजने की ज़रूरत है और जब मैं इसे पढ़ता हूं और इसे स्क्रीन पर दिखाता हूं तो यह ठीक से काम नहीं कर रहा है। मैं कुछ सैकड़ों पंक्तियाँ नहीं रखना चाहता, इसलिए मैं इसे और अधिक संक्षिप्त रूप में परिभाषित करने का प्रयास करूँगा। और प्रोजेक्ट के गुणों में नेटबीन में एन्कोडिंग "यूटीएफ -8" है

मुझे नेटबीन्स कंसोल या सीएमडी कंसोल में उपयोगकर्ता से इनपुट मिला। फिर मैं इसे स्ट्रिंग्स से बने ऑब्जेक्ट में सहेजता हूं, फिर इसे ArrayList<Ksiazka> में जोड़ता हूं जहां Ksiazka मेरी कक्षा है (मूल रूप से एक पुस्तक का गुण)। फिर मैं baza.bin फ़ाइल करने के लिए संपूर्ण ArrayList ऑब्जेक्ट को सहेजता हूं। मैं इसे कक्षा Ksiazka की वस्तुओं की पूरी सूची के माध्यम से लूप करके करता हूं, प्रत्येक स्ट्रिंग को एक-एक करके लेता हूं और इसे विधि writeUTF(oneOfStrings) का उपयोग करके फ़ाइल baza.bin में सहेजता हूं। जब मैं फ़ाइल baza.bin को पढ़ने का प्रयास करता हूं तो मुझे विशेष वर्णों (ą, ć, ę, , , ó, , ) के बजाय प्रश्न चिह्न दिखाई देता है। मुझे लगता है कि फ़ाइल और इनपुट डेटा के एन्कोडिंग में अंतर में कोई समस्या है, लेकिन ईमानदार होने के लिए मुझे इसे हल करने का कोई विचार नहीं है।

वे मेरी कक्षा की विशेषताएँ हैं Ksiazka:

private String id;
private String tytul;
private String autor;
private String rok;
private String wydawnictwo;
private String gatunek;
private String opis;
private String ktoWypozyczyl;
private String kiedyWypozyczona;
private String kiedyDoOddania;

उपयोगकर्ता से डेटा पढ़ने के लिए यह विधि है:

static String podajDana(String[] tab, int coPokazac){
    System.out.print(tab[coPokazac]);
    boolean podawajDalej = true;
    String linia = "";
    Scanner klawiatura = new Scanner(System.in, "utf-8"); 
    do{
        try {   
            podawajDalej = false; 
            linia = klawiatura.nextLine();
        }
        catch(NoSuchElementException e){
            System.err.println("Wystąpił błąd w czasie podawania wartości!"
                    + " Spróbuj jeszcze raz!");
        }
        catch(IllegalStateException e){
            System.err.println("Wewnętrzny błąd programu typu 2! Zgłoś to jak najszybciej"
                    + " razem z tą wiadomością");
        }
    }while(podawajDalej);
    return linia; 
}

String[] tab केवल स्ट्रिंग्स की सरणी है जिसे मैं स्क्रीन पर दिखाने में सक्षम होना चाहता हूं, प्रत्येक सेट (सरणी) का अपना कार्य होता है, int coPokazac एक सरणी से लाइन की संख्या है जिसे मैं दिखाना चाहता हूं।

और यह ArrayList<Ksiazka> से baza.bin फ़ाइल करने के लिए सभी डेटा सहेजता है:

static void zapiszZmiany(ArrayList<Ksiazka> bazaKsiazek){
     try{
        RandomAccessFile plik = new RandomAccessFile("baza.bin","rw");
        for(int i = 0; i < bazaKsiazek.size(); i++){
            plik.writeUTF(bazaKsiazek.get(i).zwrocId());
            plik.writeUTF(bazaKsiazek.get(i).zwrocTytul());
            plik.writeUTF(bazaKsiazek.get(i).zwrocAutor());
            plik.writeUTF(bazaKsiazek.get(i).zwrocRok());
            plik.writeUTF(bazaKsiazek.get(i).zwrocWydawnictwo());
            plik.writeUTF(bazaKsiazek.get(i).zwrocGatunek());
            plik.writeUTF(bazaKsiazek.get(i).zwrocOpis());
            plik.writeUTF(bazaKsiazek.get(i).zwrocKtoWypozyczyl());
            plik.writeUTF(bazaKsiazek.get(i).zwrocKiedyWypozyczona());
            plik.writeUTF(bazaKsiazek.get(i).zwrocKiedyDoOddania());
        }

        plik.close();
            }
        catch (FileNotFoundException ex){
            System.err.println("Nie znaleziono pliku z bazą książek!");
        }
        catch (IOException ex){
            System.err.println("Błąd zapisu bądź odczytu pliku!");
        }
}

मुझे लगता है कि उन दो तरीकों में से एक में एक समस्या है (या तो मैं इसे पढ़ते समय कुछ गलत करता हूं या कुछ गलत करता हूं जब यह writeUTF() का उपयोग करके फ़ाइल में डेटा सहेज रहा है) लेकिन फिर भी मैंने इसे हल करने के लिए कुछ चीजों की कोशिश की, उनमें से कोई भी काम नहीं किया।

व्याख्याता के साथ त्वरित बातचीत के बाद मुझे जानकारी मिली कि मैं अधिकतम JDK 8 का उपयोग कर सकता हूं।

-1
Daniel1490 19 जिंदा 2021, 17:49

1 उत्तर

सबसे बढ़िया उत्तर

आप पढ़ने और लिखने के लिए विभिन्न तकनीकों का उपयोग कर रहे हैं, और वे संगत नहीं हैं।

नाम के बावजूद, RandomAccessFile की writeUTF विधि UTF-8 स्ट्रिंग नहीं लिखती है। दस्तावेज़ीकरण:

संशोधित UTF-8 मशीन-स्वतंत्र तरीके से एन्कोडिंग।

सबसे पहले, फ़ाइल में दो बाइट्स लिखे जाते हैं, जो वर्तमान फ़ाइल पॉइंटर से शुरू होते हैं, जैसे कि writeShort विधि द्वारा अनुसरण करने के लिए बाइट्स की संख्या दी जाती है। यह मान वास्तव में लिखे गए बाइट्स की संख्या है, न कि स्ट्रिंग की लंबाई। लंबाई के बाद, स्ट्रिंग का प्रत्येक वर्ण अनुक्रम में, प्रत्येक वर्ण के लिए संशोधित UTF-8 एन्कोडिंग का उपयोग करके आउटपुट होता है।

राइटयूटीएफ दो-बाइट लंबाई लिखेगा, फिर स्ट्रिंग को यूटीएफ -8 के रूप में लिखें, सिवाय इसके कि '\u0000' वर्ण दो यूटीएफ -8 बाइट्स के रूप में लिखे गए हैं और पूरक वर्ण दो यूटीएफ -8 एन्कोडेड सरोगेट के रूप में लिखे गए हैं, बजाय सिंगल UTF-8 कोडपॉइंट अनुक्रम।

दूसरी ओर, आप new Scanner(System.in, "utf-8") और klawiatura.nextLine(); का उपयोग करके उस डेटा को पढ़ने का प्रयास कर रहे हैं। यह दृष्टिकोण संगत नहीं है क्योंकि:

  • पाठ एक सच्चे UTF-8 अनुक्रम के रूप में नहीं लिखा गया था।
  • पाठ लिखे जाने से पहले, इसकी संख्यात्मक लंबाई को इंगित करने वाले दो बाइट्स लिखे गए थे। वे पठनीय पाठ नहीं हैं।
  • writeUTF नई लाइन नहीं लिखता है। यह वास्तव में कोई समाप्ति क्रम नहीं लिखता है।

RandomAccessFile के सभी उपयोगों को हटाने और इसे एक लेखक के साथ बदलने का सबसे अच्छा समाधान है:

Writer plik = new FileWriter(new File("baza.bin"), StandardCharsets.UTF_8);
for (int i = 0; i < bazaKsiazek.size(); i++) {
    plik.write(bazaKsiazek.get(i).zwrocId());
    plik.write('\n');
    plik.write(bazaKsiazek.get(i).zwrocTytul());
    plik.write('\n');
    // ...
1
VGR 19 जिंदा 2021, 18:13
इसलिए पढ़ने और लिखने को राइटर में बदलना काम करना चाहिए। लेकिन क्या डेटा को RadomAccessFile के साथ संगत तरीके से पढ़ने का कोई विकल्प है?
 – 
Daniel1490
19 जिंदा 2021, 18:20
1
हां। आप readUTF विधि।
 – 
VGR
19 जिंदा 2021, 18:24
ठीक है, मैं जल्दी में था, इसलिए मुझे यह बात याद आ गई: क्या उपयोगकर्ता से डेटा पढ़ने का कोई विकल्प है, जैसे कि नेटबीन में cmd ​​या कंसोल से, एक तरह से RadomAccessFile के साथ संगत? मैं पूछ रहा हूं, क्योंकि मेरे पास txt फ़ाइल से किताबें पढ़ने और फिर उन्हें RandomAccessFile का उपयोग करके base.bin में जोड़ने का एक तरीका है और यह txt फ़ाइल है, मुझे लगता है कि डिफ़ॉल्ट रूप से, UTF-8 के रूप में एन्कोड किया गया है। तो अगर स्कैनर RandomAccessFIle के साथ संगत नहीं है, तो RandomAccessFile को राइटर में नहीं बदलना एक और समस्या बना रहा है?
 – 
Daniel1490
19 जिंदा 2021, 18:43
1
आम तौर पर आप उपयोगकर्ता इनपुट को स्ट्रिंग्स के रूप में पढ़ते हैं। आप उन स्ट्रिंग्स के साथ कुछ भी कर सकते हैं, जिसमें उन्हें RandomAccessFile का उपयोग करके लिखना शामिल है। यदि आप पूछ रहे हैं कि क्या एक ही कोड का उपयोगकर्ता इनपुट पढ़ने और RandomAccessFile.writeUTF का उपयोग करके बनाई गई फ़ाइल से पढ़ने में सक्षम होना संभव है, तो उत्तर नहीं है।
 – 
VGR
19 जिंदा 2021, 18:52
1
हां। लेखक और स्कैनर का कोई विशेष प्रारूप नहीं है: UTF-8 टेक्स्ट सिर्फ टेक्स्ट है।
 – 
VGR
19 जिंदा 2021, 19:31