Czytanie pliku txt, nadmiarowe znaki, gdy występują polskie litery

0

Próbuję wyświetlić dane z pliku tekstowego, lecz w przypadku korzystania z polskich znaków pojawiają się jakieś nadmiarowe znaki. Nie wiem o co chodzi, a potrzebuję dowiedzieć się jak wczytać dane, które połączę w jednym łańcuchu znaków. Problem z kodowaniem? Niby plik ma ustawione kodowanie UTF-8 (używam Visual Studio Code).

Jak widać pojawiają się jakieś dodatkowe znaki.
output.png

Klasa App.java

import java.util.Scanner;
import java.io.File;

public class App {
    public static void main(String[] args) throws Exception {
        String filePath = "C:\\Users\\ExampleUser\\Desktop\\java\\users.txt";
        File file = new File(filePath);
        Scanner scanner = new Scanner(file, "UTF-8");

        String line = scanner.nextLine();
        String[] values = line.split(",");

        String queryInsert = String.format(
            "INSERT INTO users VALUES (%s, %s, %s, %s)",
            values[0], values[1], values[2], values[3]
        );

        System.out.println(queryInsert);

        scanner.close();
    }
}

Zawartość users.txt

1,imię,nazwisko,płeć
0

Obstawiałbym, że wina lezy w

"C:\\Users\\ExampleUser\\Desktop\\java\\users.txt

Otwórz to w jakimś notepad++ czy coś.

3

Coś jest nie tak.

Obrazek pokazuje stringi w cienkich apostrofach, kod nie daje ku temu powodu.
Pachnie, jakby to nie było z tego samego wykonania, czyli z innej wersji programu.

0

@testerr: Umieść tu plik users.txt jako załącznik

0

@diligentia:
@AnyKtokolwiek:

Zgadza się, pomyliłem się z kodem, ponieważ w najnowszej wersji dopisałem apostrofy. Już dodaję aktualny kod oraz pliki users.txt i output2.png. Mam nadzieję, że uda się coś wymyślić o co chodzi z tymi znakami :)

Dodatkowe informacje: używam Visual Studio Code z zainstalowanym rozszerzeniem Java Extension Pack. Program uruchamiam klikając ikonkę Run lub Debug w prawym górnym rogu.

Aktualny kod

import java.util.Scanner;
import java.io.File;

public class App {
    public static void main(String[] args) throws Exception {
        String filePath = "C:\\Users\\ExampleUser\\Desktop\\java\\users.txt";
        File file = new File(filePath);
        Scanner scanner = new Scanner(file, "UTF-8");

        String line = scanner.nextLine();
        String[] values = line.split(",");

        String queryInsert = String.format(
            "INSERT INTO users VALUES (%s, '%s', '%s', '%s')",
            values[0], values[1], values[2], values[3]
        );

        System.out.println("Query:");
        System.out.println(queryInsert);

        scanner.close();
    }
}

Output2
output2.png

2

A skad drugie zamkniecie nawiasu?

0

@stivens:
@AnyKtokolwiek:

Dobrze panowie wygląda na to, że problem tkwił w okienku wyświetlanym w zakładce terminal w Visual Studio Code. Wspomniane wcześniej rozszerzenie dla Java odpala jakieś okienko, w którym wyświetla informacje z konsoli. Jak stworzyłem projekt za pomocą Intellij IDEA to string wyświetlany jest poprawnie. Dla ręcznej kompilacji za pomocą javac z poziomu CMD również jest ok. Śmiech na sali, ale widocznie na czas pisania w Java przerzucę się na pełnoprawne IDE dla tego języka.

Zainteresowanym dziękuję za chęci udzielenia pomocy, choć wygląda na to, że niekoniecznie była potrzeba, ale i tak dzięki :)

output_intellij.png

output_cmd.png

0

Strasznie to pachnie XY, a kwerendę przypomnę budujesz nieprofesjonalnie.

Co NAPRAWDĘ zamierzasz?

0

@AnyKtokolwiek:

Mam plik tekstowy (rozszerzenie *.txt, ale chyba powinno być *.csv) w którym każdy wiersz zawiera kilkanaście oddzielonych od siebie wartości. Całość ma trafić do gotowej tabeli w bazie danych. Nie można korzystać z importerów. Wierszy jest bardzo dużo, więc ręczne pisanie poleceń INSERT INTO nie ma sensu. Pomyślałem, że napiszę program, który otworzy plik, dla każdego wiersza sklei zapytanie i następnie zapisze taki string do drugiego pliku *.txt z którego potem skopiuję gotowe polecenia INSERT INTO. Chodzi o same polecenia INSERT INTO. Z poziomu Java nie muszę robić połączenia do bazy danych, nawet nie musiałem używać Java, ale od wczoraj jestem w trakcie realizacji innego zadania w tym języku (na razie na kartce rozpisuję co jest potrzebne) i po prostu postanowiłem go użyć. Pod ręką miałem Visual Studio Code i myślałem, że wystarczy, ale chyba jednak nie :P Piszę w różnych technologiach, bo taki mam wymóg (studia), co oczywiście sprawia, że pewne rzeczy zapominam, dużo rzeczy też mi się myli itd.

Jeśli masz ciekawe sugestie jak poradzić z zapamiętywaniem kilku różnych składni, czy przełączaniem pomiędzy narzędziami to chętnie poczytam. A o innym rozwiązanie mojego nazwijmy "problemu" również z chęcią poczytam. Pewnie w takim Pythonie można to zrobić szybciej, kojarzę jakieś dataframe z pandas, ale znowu musiałbym o tym na nowo poczytać.

0

Jeśli rzeczywiście jest jak przedstawiasz - wymóg na te wiele technologii - to strasznie dziwnie wybrałeś sobie płaszczyznę cięcia.
Wykonaj to w Javie, w sposób czysty, przynajmniej się nauczysz w miarę pozytywnego wzorca - bo na razie jest antynauka

BTW ile płci jest u ciebie? To na AGH może?

https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html

Przy okazji spodziewaj się jakiegoś zysku na szybkości.

1
testerr napisał(a):

Dobrze panowie wygląda na to, że problem tkwił w okienku wyświetlanym w zakładce terminal w Visual Studio Code. Wspomniane wcześniej rozszerzenie dla Java odpala jakieś okienko, w którym wyświetla informacje z konsoli. Jak stworzyłem projekt za pomocą Intellij IDEA to string wyświetlany jest poprawnie.

Ściągam proste konsolowe Ubuntu

docker run -it --rm -p 22:22 ubuntu bash

Do niego doinstalowane OpenSSH i user nazwany cat ;)

useradd -m cat 
passwd cat
apt-get update
apt-get install openssh-server
service ssh start

kopiuję user.txt do ubuntu i loguję się do ubuntu jako użytkownik cat

scp users.txt [email protected]:~/
ssh [email protected]

Po zalogowaniu

$ ls
users.txt
$ cat users.txt 
1,imię,nazwisko,płeć$ 

Zainstaluję javę

apt-get install openjdk-11-jdk

Weźmy prosty przykład Goose.java, zbudujmy z niego jar
src/main/resources/META-INF/MANIFEST.MF

main

Goose.java

package pl.bv.p70;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class Goose {

    public static void main(String[] args) {

        final String text = "Zażółć gęślą jaźń";
        System.out.println(text);

        try (BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(System.out,"UTF-8"))) {
            bufferedWriter.write(text);
            bufferedWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

jar przekopiujmy do ubuntu

scp goose.jar [email protected]:~/

uruchamiamy w ubuntu

cat@29f6c18466d6:~$ java -jar goose.jar 
Za???? g??l? ja??
Zażółć gęślą jaźń

Pierwsza gęś ma niepokolorowaną po polsku jaźń, ale druga z poprawnie zapodanym UTF-8 w kodzie źródłowym już jest żółta.

Wnioski
Masz jakiś problem ze środowiskiem? Startujesz jakiś bardzo bazowy obraz, np ubuntu który domyślnie nie ma ma nic, nawet vi/vim, trzeba sobie doinstalować.
Na takim szkielecie sprawdzasz co i jak działa/nie działa.
Nie opierasz się tylko na plugin-ach pod IDE na Windows. Czysty obraz, dobudowujesz od zera tylko co potrzebne, i dopiero na tym testujesz.

1
AnyKtokolwiek napisał(a):

https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html

Przy okazji spodziewaj się jakiegoś zysku na szybkości.

PreparedStatement - wiadomo, że bezpieczniej. Ale czy kiedykolwiek zmierzyłeś ten zysk szybkości?

0

@testerr: Jeśli to ma być plik tylko z insertami, to po co powtarzasz to insert into .., wystarczy raz:

INSERT INTO tabelka VALUES
(1, 'jan','nepomucen',m),
(2, 'karol','motyl',m),
...
(1000,'koniec','end',m);
0

@AnyKtokolwiek: Miałem na myśli to, że na każdym kursie używam innych rozwiązań. Nie chcę wchodzić w szczegóły, ale osoby, które studiowały zapewne wiedzą jak jest - szeroka pokazówka różnych zagadnień, od teorii po praktykę. Aktualnie na jednym kursie mam do napisania program w Java z bazą danych (dzięki za link do prepared statements), testami jednostkowymi i kilkoma innymi rzeczami o których na razie nie mam pojęcia. W skrócie wszystkiego będę musiał się nauczyć przy okazji powtórzyć podstawy, bo ostatni raz w Java pisałem w zeszłym roku. Szczerze mówiąc sporo zapomniałem, ale też nie miałem dużej wiedzy/doświadczenia. Drugi kurs zachacza o tematykę baz danych (relacyjne, NoSQL) z różnymi ćwiczeniami. Na innym przedmiocie piszemy w Pythonie. Nie ukrywam, że skakanie po językach jest męczące, ale nic na to nie poradzę. No tak przeważnie jest na studiach, trzeba jakoś sobie radzić. Oprócz tego mam w planach zrobić dla siebie mały projekt i zastanawiam się w czym to napiszę, bo niespecjalnie ciągnie mnie do Java, choć zapewne za pomocą Java łatwiej nauczę się pisać kod niż np. w PHP z frameworkiem.

@cs: Dzięki, faktycznie jest taka składnia. Nie pomyślałem, że mogę użyć takiego zapisu.

@BraVolt: Dzięki za cenne wskazówki. Słyszałem o Dockerze, ale nie zagłębiałem się w temat, bo w sumie za cienki jestem na takie rzeczy. Np. w Java nie wiem jak używa się narzędzi do zarządzania pakietami/bibliotekami, a w Pythonie wystarczy wpisać pip install, w PHP jest composer. Myślę, że mam zbyt wiele braków w podstawach, dlatego póki co omijam dodatkowe toolsy jak się da, ograniczając się jedynie do git.

1
testerr napisał(a):

@BraVolt: Dzięki za cenne wskazówki. Słyszałem o Dockerze, ale nie zagłębiałem się w temat, bo w sumie za cienki jestem na takie rzeczy. Np. w Java nie wiem jak używa się narzędzi do zarządzania pakietami/bibliotekami, a w Pythonie wystarczy wpisać pip install, w PHP jest composer. Myślę, że mam zbyt wiele braków w podstawach, dlatego póki co omijam dodatkowe toolsy jak się da, ograniczając się jedynie do git.

Maven, raz wpisujesz dla całego projektu, np. żeby mieć całą bibliotekę z wszystkimi zależnościami

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>3.6.0</version>
    <scope>test</scope>
</dependency>

póżniej tylko kiedy potrzeba 1 linijka

import org.mockito.Mockito;

Sam Maven? Tworząc projekt np. IntelliJ zaznaczasz, że ma być na Maven i to wszystko.

Docker. Wiem, na oczątku trudno, ale im szybciej zrobisz 2 rzeczy:

  1. zaczniesz się uczyć z materiałów w j. angielskim
  2. odkryjesz, że świat programisty to nie tylko Windows, ale też podstawowe "toolsy"
    tym szybciej osiągniesz znaczący postęp w nauce.

Ps
jest oczywiście Gradle, może być Gradle a nie Maven.

1 użytkowników online, w tym zalogowanych: 0, gości: 1