我正在遍历一个字符串(路径)列表并使用File(“path”)来打开这些文件(mp3)。然后,我获取元数据并在对象(Song)中设置元数据的值。然后我将该歌曲添加到列表中并将其传递给序列化文件。
我的问题是,当我填充要发送的歌曲列表时,在调试中它的大小为49K对象,并且都为空。但是每个对象都有我设置的值。如果我尝试调整大小,我会得到一个空指针异常。
以下是相关代码:
Song Class(非常标准......唯一关心的是Serializable的实现):
package com.bkane56.mp3;
import java.io.Serializable;
public class Song implements Serializable {
private final static long serialVersionUID = 1L;
private String path;
private String songName;
private String artistName;
private String albumName;
private String releaseDate;
private String trackNumber;
private String composer;
private String genre;
private String length;
private String publisher;
private int artistID;
private int albumID;
public Song(){
}
public Song(String path) {
this.path = path;
}
public Song(String path, String songName, String artistName,
String albumName, String releaseDate, String trackNumber,
String composer, String genre, String length, String publisher,
int artistID, int albumID) {
this.path = path;
this.songName = songName;
this.artistName = artistName;
this.albumName = albumName;
this.releaseDate = releaseDate;
this.trackNumber = trackNumber;
this.composer = composer;
this.genre = genre;
this.length = length;
this.publisher = publisher;
this.artistID = artistID;
this.albumID = albumID;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getSongName() {
return songName;
}
public void setSongName(String songName) {
this.songName = songName;
}
public String getArtistName() {
return artistName;
}
public void setArtistName(String artistName) {
this.artistName = artistName;
}
public String getAlbumName() {
return albumName;
}
public void setAlbumName(String albumName) {
this.albumName = albumName;
}
public String getReleaseDate() {
return releaseDate;
}
public void setReleaseDate(String releaseDate) {
this.releaseDate = releaseDate;
}
public String getTrackNumber() {
return trackNumber;
}
public void setTrackNumber(String trackNumber) {
String[] tNumber = trackNumber.split("/");
if (tNumber.length > 1) {
this.trackNumber = tNumber[0];
}else {
this.trackNumber = trackNumber;
}
}
public String getComposer() {
return composer;
}
public void setComposer(String composer) {
this.composer = composer;
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public int getArtistID() {
return artistID;
}
public void setArtistID(int artistID) {
this.artistID = artistID;
}
public int getAlbumID() {
return albumID;
}
public void setAlbumID(int albumID) {
this.albumID = albumID;
}
public String getLength() {
return length;
}
public void setLength(Long microseconds) {
int mili = (int) (microseconds / 1000);
int sec = (mili / 1000) % 60;
int min = (mili / 1000) / 60;
length = String.format("%d:%02d", min, sec);
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("Values for this song:");
sb.append("\n\tArtist: " + artistName);
sb.append("\n\tTitle: " + songName);
sb.append("\n\tRelease Date: " + releaseDate);
sb.append("\n\tTrack Number: " + trackNumber);
sb.append("\n\tComposer: " + composer);
sb.append("\n\tPublisher: " + publisher);
sb.append("\n\tLength: " + length);
sb.append("\n");
System.out.println(sb.toString());
return null;
}
}
调用以填充歌曲和歌曲列表并传递要写入的列表:
public static void savePopulatedList(){
List<Song> myList = populateFromFile();
SerialUtilities utilities = new SerialUtilities();
utilities.saveSerializedSongInfoFile(myList);
}
以下是获取元数据和设置Song对象中的值的方法:
public class PopulateSongs {
private static List<Song> songList;
private static Song song;
public static List<Song> populateFromFile() {
List<String> songs = DirWalker.readSerializedSongPathsFile();
List<Song> listOfSongs = new ArrayList<>();
for (String item : songs) {
song = new Song();
File file = new File(item);
System.out.println(item);
try {
AudioFileFormat fileFormat = AudioSystem.getAudioFileFormat(file);
if (fileFormat instanceof TAudioFileFormat) {
Map<?, ?> properties = ((TAudioFileFormat) fileFormat).properties();
song.setPath(item);
song.setArtistName((String) properties.get("author"));
song.setAlbumName((String) properties.get("album"));
song.setSongName((String) properties.get("title"));
song.setReleaseDate((String) properties.get("date"));
song.setGenre((String) properties.get("mp3.id3tag.genre"));
song.setTrackNumber((String) properties.get("mp3.id3tag.track"));
song.setLength((Long) properties.get("duration"));
song.setComposer((String) properties.get("mp3.id3tag.composer"));
song.setPublisher((String) properties.get("mp3.id3tag.publisher"));
song.setAlbumID(1);
song.setArtistID(1);
songList.add(song);
} else {
throw new UnsupportedAudioFileException();
}
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return listOfSongs;
}
.....continues>>>
当它到达以下要保存时,列表的值为null但大小超过49K。
public void saveSerializedSongInfoFile (List<Song> sl) {
// List<Song> sortedSongList = SortSongList.sortSongBy(sl, SongComparator.Order.ARTIST);
System.out.println("Size of Song List To Be Written: " + s1.size() + "\n");
try (ObjectOutputStream objectOutputStream =
new ObjectOutputStream(new FileOutputStream(savePath))) {
objectOutputStream.writeObject(sl);
} catch (IOException e) {
e.printStackTrace();
}
}
现在我感到困惑,这是在IntelliJ中运行调试时SongList的输出。列表有一个大小,对象具有准确的值,但整个对象为空。
这是调试值(我扩展了一对以显示值:
songs = {ArrayList@511} size = 49783
listOfSongs = {ArrayList@512} size = 49782
0 = {Song@515} "null"
path = "m:\tunes\10,000 Maniacs\In My Tribe\01 - What's The Matter Here_.mp3"
songName = "What's The Matter Here?"
artistName = "10,000 Maniacs"
albumName = "In My Tribe"
releaseDate = "1987"
trackNumber = "1"
composer = "Natalie Merchant/Robert Buck"
genre = "Soft Rock"
length = "4:51"
publisher = "Elektra"
artistID = 1
albumID = 1
1 = {Song@669} "null"
2 = {Song@670} "null"
3 = {Song@671} "null"
4 = {Song@672} "null"
5 = {Song@673} "null"
6 = {Song@674} "null"
7 = {Song@675} "null"
8 = {Song@676} "null"
9 = {Song@677} "null"
10 = {Song@678} "null"
11 = {Song@679} "null"
12 = {Song@680} "null"
13 = {Song@681} "null"
14 = {Song@682} "null"
15 = {Song@683} "null"
16 = {Song@684} "null"
17 = {Song@685} "null"
18 = {Song@686} "null"
19 = {Song@687} "null"
20 = {Song@688} "null"
21 = {Song@689} "null"
22 = {Song@690} "null"
23 = {Song@691} "null"
24 = {Song@692} "null"
25 = {Song@693} "null"
26 = {Song@694} "null"
path = "m:\tunes\AC-DC\1 Studio albums\1974 High Voltage (Australian Editions) @320\02 - She's Got Balls.mp3"
songName = "She's Got Balls"
artistName = "AC/DC"
albumName = "High Voltage"
releaseDate = "1975"
trackNumber = "2"
composer = null
genre = "Hard Rock"
length = "4:48"
publisher = "Albert Productions"
artistID = 1
albumID = 1
27 = {Song@695} "null"
28 = {Song@696} "null"
29 = {Song@697} "null"
30 = {Song@698} "null"
31 = {Song@699} "null"
.......and this continues for the rest of the array.
任何了解这一点的人,你能向我解释一下......最好还是修复:)。
答案 0 :(得分:2)
这些项目不是1 = {Song@669} "null"
index = {ClassName@ObjectId} "Result of 'toString()'"
。你是调试器给你看的:
Song#toString
由于您的@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("Values for this song:");
sb.append("\n\tArtist: " + artistName);
sb.append("\n\tTitle: " + songName);
sb.append("\n\tRelease Date: " + releaseDate);
sb.append("\n\tTrack Number: " + trackNumber);
sb.append("\n\tComposer: " + composer);
sb.append("\n\tPublisher: " + publisher);
sb.append("\n\tLength: " + length);
sb.append("\n");
System.out.println(sb.toString());
return null;
}
看起来像这样:
toString
很清楚为什么它会显示“null”。 null
应该返回一个对象的String表示。您的实现只打印此表示并返回sb.toString()
。您需要返回@Override
public String toString(){
//...
return sb.toString();
}
:
public static String changeFirst (String s, char oldChar, char newChar)